home *** CD-ROM | disk | FTP | other *** search
/ Multimedia Jumpstart / Multimedia Microsoft Jumpstart Version 1.1a (Microsoft).BIN / develpmt / drivers / mscdex / hitachi / cdread.asm < prev    next >
Encoding:
Assembly Source File  |  1990-10-15  |  70.8 KB  |  2,134 lines

  1. ; ***************************************************************************
  2. ; *                                                                         *
  3. ; * Hitachi CDR-3600/1600S C D - R O M Device Driver                        *
  4. ; * Copyright reserved by Hitachi, Ltd.                                     *
  5. ; *                                                                         *
  6. ; * CDREAD version 8a.                                                      *
  7. ; *                                                                         *
  8. ; * This module provides the function CDREAD() which interfaces directly    *
  9. ; * with Hitachi CDR-3600/1600S drivese for IBM PC/XT/AT.                   *
  10. ; *                                                                         *
  11. ; *                                                                         *
  12. ; * History:                                                                *
  13. ; *                                                                         *
  14. ; * Created.                                                                *
  15. ; *     Mar. 20.1985 -by- TE                                                *
  16. ; *                                                                         *
  17. ; * Modified                                                                *
  18. ; *     Sep. 19.1987 -by- TE                                                *
  19. ; *                                                                         *
  20. ; * Modified                                                                *
  21. ; *     Mar. 30.1989 -by- T.E                                               *
  22. ; *                                                                         *
  23. ; * Modified (v2.20)                                                        *
  24. ; *     Mon Jul 16 1990 -by- Michael Edwards                                *
  25. ; *                                                                         *
  26. ; *     Moved initializing timing variables to CD.ASM's cdrom_init().       *
  27. ; *                                                                         *
  28. ; *     Changed installing a timer interrupt routine, and use of the timing *
  29. ; *     variables CLOCK_1 and CLOCK_2, to use the system 18Hz long interger *
  30. ; *     count (at 040:006c) in the routines set_time_1(), set_time_2(),     *
  31. ; *     check_time_1() and check_timer2().                                  *
  32. ; *                                                                         *
  33. ; *     Removed all cli/sti's except the pair in the DMA routine.           *
  34. ; * Modified (v2.20)                                                        *
  35. ; *     10/1/90 -by- JohnYG                                                 *
  36. ; *     Added some short jumps after assembling with -W2                    *
  37. ; *     Final Release (v2.20)                                               *
  38. ; *                                                                         *
  39. ; ***************************************************************************
  40. ;    << for debug >>
  41. ;---------------------
  42. FALSE   EQU     0
  43. MSCDEX  equ     0               ;for CD-ROM EXT. device driver
  44. ;-------------------------
  45.  
  46.         INCLUDE CDREAD.AT
  47.  
  48. PRINT_STRING    MACRO
  49.         MOV     AH,9
  50.         INT     21H
  51.                 ENDM
  52.  
  53. IN_PB   MACRO
  54.         CALL    IN_PB_SUB
  55.         ENDM
  56. PPI_PA  MACRO
  57.         MOV     DX,BP
  58.         DEC     DX
  59.         ENDM
  60. PPI_PB  MACRO
  61.         MOV     DX,BP
  62.         ENDM
  63. PPI_PC  MACRO
  64.         MOV     DX,BP
  65.         INC     DX
  66.         ENDM
  67. PPI_CR  MACRO
  68.         MOV     DX,BP
  69.         INC     DX
  70.         INC     DX
  71.         ENDM
  72. DATA_PORT       MACRO
  73.         MOV     DX,BP
  74.         ADD     DX,3
  75.         ENDM
  76. INT_PORT        MACRO
  77.         MOV     DX,BP
  78.         ADD     DX,5
  79.         ENDM
  80. NOPL    MACRO
  81.         JMP     SHORT $+2
  82.         ENDM
  83. ;
  84.         EXTRN   ECC             :NEAR
  85.  
  86.         PUBLIC  CDREAD
  87.         PUBLIC  INSB_LOOP
  88.         PUBLIC  _INSB_LOOP_ENT
  89.         PUBLIC  _STATUS_COMMAND
  90.  
  91.         PUBLIC  BUF
  92.         PUBLIC  CPU_MODE
  93.         PUBLIC  CLOCK_MODE
  94.         PUBLIC  CURRENT_IF_MODE
  95.         PUBLIC  STA_CODE
  96.         PUBLIC  TWICE
  97.         PUBLIC  IF_FLAG
  98.         PUBLIC  CLOCK_COUNT
  99.         PUBLIC  ERRCNT
  100.         PUBLIC  CURRENT_IF
  101.  
  102. _TEXT   SEGMENT PARA PUBLIC 'CODE'
  103. CDREAD  PROC    FAR
  104.         ASSUME  CS:_TEXT,ES:_TEXT,DS:_TEXT
  105.  
  106. BEGIN:  JMP     START
  107.  
  108.  
  109. ;--------------------------------------------------------------------
  110.         DB      "CDRD8A  Ver. 1.00 "
  111.         DB      "FOR PC/XT/AT      "
  112.         DB      "(C) Copyright Hitachi, Ltd. 1985,1989 "
  113. ;--------------------------------------------------------------------
  114. ;       M Y   W O R K   A R E A
  115. ;----------------------------------------------------------------------
  116.  
  117. RAW_DATA        DB      12 DUP(0)
  118. HEADER          DB      4 DUP(?)
  119. BUF             DB      2340 DUP (?)
  120.  
  121. BX_SAVE         LABEL   WORD
  122. MYDTA_OFF       DW      ?               ;DATA TRANSFER ADDRESS_OFFSET
  123. ES_SAVE         LABEL   WORD
  124. MYDTA_SEG       DW      ?               ; "      "        "   _SEGMENT
  125. AH_SAVE         LABEL   BYTE
  126. COM_CODE        DB      ?               ;COMMAND CODE
  127. AL_SAVE         LABEL   BYTE
  128. CD_TOTAL_AL     DB      ?               ;TOTAL DATA BLOCKS TO READ
  129. CH_SAVE         LABEL   BYTE
  130. CD_MIN          DB      ?               ;MINUTE
  131. CL_SAVE         LABEL   BYTE
  132. CD_SEC          DB      ?               ;SECOND
  133. DH_SAVE         LABEL   BYTE
  134. CD_BLK          DB      ?               ;DATA BLOCK
  135. DL_SAVE         LABEL   BYTE
  136. DRIVE_NO        DB      ?               ;DRIVE NUMBER
  137. SI_SAVE         DW      ?
  138. DI_SAVE         DW      ?
  139. S_ES_SAVE       DW      ?
  140. S_BX_SAVE       DW      ?
  141. ;
  142. CD_TOTAL        DW      WORD
  143. CD_CNT          DW      ?
  144. COMC            DB      0FFH            ;CLEAR COMMAND COUNTER CODE
  145. COM             DB      7 DUP(?)        ;COMMAND CODE
  146. STA_CODE        DB      0               ;STATUS CODE
  147. ERRCNT          DB      10              ;ERROR COUNT FOR RETRY
  148. ;
  149. CURRENT_IF_B    LABEL   BYTE
  150. CURRENT_IF      DW      300H
  151. CURRENT_IF_MODE DB      0FFH    ;0FFH - NOT CHECKED, 0 - SOFT OK, 1 - SOFT NG
  152. CURRENT_DRIVE   DB      8 DUP (0FFH)
  153. ;
  154. CHK_DRV_WORK    LABEL   BYTE
  155. IF_FLAG         DB      0
  156. TWICE           DB      0
  157.  
  158. time_1          dw      0
  159. time_2          dw      0
  160.  
  161. PAUSE_FLG       DB      0       ;DRIVE PAUSE FLAG
  162. COM_COUNT       DW      1
  163. TRNS_MODE       DB      0       ;0 - SOFT, 1 - DMA
  164. MODE_SET_TRNS   DB      0       ;0 - AUTO(DEFAULT), 1 - DMA ONLY
  165. DRIVE_NO_MASK   DB      ?       ;DRIVE NUMBER MASK DATA
  166. CLOCK_MODE      DB      0FFH    ;0FFH - NOT CHECKED,  0 - CHECKED OK, 1 - NG
  167. CLOCK_COUNT     DB      0
  168. CPU_MODE        DB      0FFH    ;0FFH - NOT CHECKED,  0-8088, 2-80286
  169. GENERAL_FLAG    DB      0
  170. MAX_DRIVE       DB      0       ;3 or 7 , 0 - NOT CHECKED
  171. READ_MODE       DB      0       ;0 -- 2048, 1 -- 2352(12*00h+HEADER+2048+EDC/ECC)
  172. ;
  173. ;
  174. ; FUNCTION TABLE
  175. ;
  176. FUNCTBL         LABEL   BYTE
  177.         DW      INIT            ;0 INITIALIZE
  178.         DW      INPUT           ;1 READ
  179.         DW      SEEK            ;2 SEEK
  180.         DW      SEEKW           ;3 SEEK AND WAIT
  181.         DW      STATUS          ;4 STATUS
  182.         DW      DISKST          ;5 DISK STATUS
  183. ;
  184. ;------
  185.         ifdef   MSCDEX
  186.         DW      READ_EXT        ;6 READ EXT more than 256 blks
  187.         else
  188.         DW      ERROR_COM       ;6 reserved
  189.         endif
  190.  
  191. ;------
  192.         ifdef   MSCDEX
  193.         DW      UCOM            ;7 READ UCOM RAM -- ONLY FOR CD-EXT.
  194.         else
  195.         DW      ERROR_COM       ;7 reserved
  196.         endif
  197. ;------
  198.         DW      SEEK_TO_LEAD    ;8 SEEK TO LEAD IN
  199.         DW      READ_SUBQ       ;9 READ SUBCODE Q
  200.         DW      PAUSE           ;A PAUSE
  201.         DW      AUDIO           ;B AUDIO
  202.         DW      STOP            ;C STOP
  203.         DW      AUDIO_EXT       ;D AUDIO EXTENDED (L/R)
  204.         DW      AUDIO_TNO       ;E AUDIO BY TNO
  205.         DW      OPEN            ;F OPEN
  206.         DW      CLOSE           ;10 CLOSE
  207.         DW      P_A_MED         ;11 PREVENT/ALLOW MEDIUM
  208.         DW      SET_POWER       ;12 SET POWER SAVE
  209.         DW      ERROR_COM       ;13 reserved
  210. ;------
  211.         ifdef   MSCDEX
  212.         DW      CH_CTRL         ;14 Audio ch. control
  213.         else
  214.         DW      ERROR_COM       ;14 reserved
  215.         endif
  216. ;------
  217.         DW      VERSION         ;15 VERSION
  218.         DW      ERROR_COM       ;16 reserved
  219.         DW      MODE_SET        ;17 MODE SET
  220.         DW      GENERAL         ;18 GENERAL
  221. ;;;     dw      direct          ;19 direct communicate
  222. ;;;     dw      read_2352       ;1A read 2352 byte mode
  223. ;----------------------------------------------------------------------
  224. ; L O C A L   P R O C E D U R E S
  225. ;----------------------------------------------------------------------
  226. IN_SAVE PROC    NEAR
  227.         MOV     BYTE PTR COM_CODE,AH    ;SAVE COMMAND CODE
  228.         MOV     CD_TOTAL_AL,AL
  229.         MOV     BYTE PTR CD_MIN,CH
  230.         MOV     CD_SEC,CL
  231.         MOV     BYTE PTR CD_BLK,DH
  232.         MOV     DRIVE_NO,DL
  233.         MOV     MYDTA_OFF,BX    ;SAVE DTA ADDRESS_OFFSET
  234.         MOV     MYDTA_SEG,ES    ;                _SEGMENT
  235.         MOV     DI_SAVE,DI
  236.         MOV     SI_SAVE,SI
  237.         RET
  238. IN_SAVE ENDP
  239. ;----------------------------------------------------------------------
  240. ; BINARY TO BCD
  241. ;       INPUT   CD_MIN  MINUTE in binary
  242. ;               CD_SEC  SECOND  "    "
  243. ;               CD_BLK  BLOCK   "    "
  244. ;       OUTPUT  COM+1   MINUTE in BCD
  245. ;               COM+2   SECOND  "  "
  246. ;               COM+3   BLOCK   "  "
  247. ;
  248. ;----------------------------------------------------------------------
  249. BCD     PROC    NEAR            ;CONVERT BINARY TO BCD CODE
  250.         MOV     CX,3            ;SET 3 IN COUNTER
  251.         MOV     DI,CS
  252.         MOV     ES,DI           ;SET PTR COM+1  IN ES:DI
  253.         MOV     DI,OFFSET COM+1
  254.         MOV     SI,OFFSET CD_MIN        ;SET PTR CD_MIN IN DS:SI
  255. BCD_S:
  256.         MOV     BL,10           ;SET 10 AS DIVISOR
  257. BCD_1:                          ;CONVERT CD_X TO BCD AND STORE IN COM+X
  258.         XOR     AH,AH
  259.         LODSB
  260.         DIV     BL
  261.         SHL     AL,1            ;    AL=UPPER DIGIT, AH=LOWER DIGIT
  262.         SHL     AL,1            ;    MULTIPLY AL BY BCD 10
  263.         SHL     AL,1
  264.         SHL     AL,1            ;    NOW UPPER DIGIT IN UPPER NIBBLE OF AL
  265.         ADD     AL,AH           ;    ADD AH AND AL TO GET BCD CODE
  266.         STOSB                   ;    STORE IT IN COM+X
  267.         LOOP    BCD_1
  268.         RET
  269. BCD     ENDP
  270. ;----------------------------------------------------------------------
  271. ; UPDATE DATA BLOCK NUMBER
  272. ;       INPUT/OUTPUT    MYDTA           DTA Address
  273. ;                       CD_MIN          Minute
  274. ;                       CD_SEC          Second
  275. ;                       CD_BLK          Data Block
  276. ;       OUTPUT          CY              1 = Out of Range, 0 = No Error
  277. ;
  278. ;----------------------------------------------------------------------
  279. UPDATE  PROC    NEAR
  280.         ADD     WORD PTR MYDTA_OFF,2048         ;UPDATE DATA TRANSFER ADDRESS
  281.         JNC     UPD_1                           ;
  282.         JMP     SHORT   UPD_0
  283. UPDATE_2352:
  284.         ADD     WORD PTR MYDTA_OFF,2352         ;UPDATE DATA TRANSFER ADDRESS
  285.         JNC     UPD_1                           ;
  286. UPD_0:
  287.         ADD     WORD PTR MYDTA_SEG,1000H        ;    INCREMENT SEGMENT
  288. ;;;     JMP     SHORT   UPD_1
  289. UPD_1:  XOR     AL,AL
  290.         INC     BYTE PTR CD_BLK                 ;INCREMENT DATA BLOCK
  291.         CMP     BYTE PTR CD_BLK,MAX_BLOCK       ;CHECK   DATA BLOCK >= 75
  292.         JB      OK_UPDATE                       ;IF LESS THAN 75, RETURN
  293.         MOV     BYTE PTR CD_BLK,AL              ;SET DATA BLOCK 0
  294.         INC     BYTE PTR CD_SEC                 ;INCREMENT SECOND
  295.         CMP     BYTE PTR CD_SEC,MAX_SECOND      ;CHECK   SECOND >= 60
  296.         JB      OK_UPDATE                       ;IF LESS THAN 60, RETURN
  297.         MOV     BYTE PTR CD_SEC,AL              ;SET SECOND 0
  298.         INC     BYTE PTR CD_MIN                 ;INCREMENT MINUTE
  299.         CMP     BYTE PTR CD_MIN,MAX_MINUTE      ;CHECK  MINUTE >= MAX_MINUTEUTE
  300. OK_UPDATE:
  301.         CMC
  302.         RET
  303. UPDATE  ENDP
  304. ;----------------------------------------------------------------------
  305. ; CHECK ID
  306. ;       INPUT   CD_MIN etc.     Data Block Number
  307. ;               BUF             ID of CD-ROM Data
  308. ;       OUTPUT  ZR              1 = ID Error, 0 = No Error
  309. ;
  310. ;----------------------------------------------------------------------
  311. CHK_ID  PROC    NEAR
  312.         CALL    BCD                     ;CONVERT DATA BLOCK NUMBER IN BCD
  313.         MOV     AX,WORD PTR COM+1       ;CHECK ID
  314.         CMP     AX,WORD PTR BUF         ;    CHECK MINUTE AND SECOND
  315.         JNZ     CHK_ID_E                ;    JUMP IF ID ERROR
  316.         MOV     AL,BYTE PTR COM+3       ;    M AND S IS O.K. CHECK BLOCK
  317.         CMP     AL,BYTE PTR BUF+2       ;    CHECK DATA BLOCK
  318.         JNZ     CHK_ID_E                ;    JUMP IF DATA BLOCK ERROR
  319.         INC     AL                      ;    RESET ZR
  320.         RET                             ;NORMAL RETURN
  321. CHK_ID_E:
  322.         XOR     AL,AL                   ;SET ZR
  323.         RET                             ;ERROR RETURN
  324. CHK_ID  ENDP
  325. ;----------------------------------------------------------------------
  326. ; CHECK DRIVE
  327. ;
  328. ;       INPUT   None
  329. ;       OUTPUT  ZR      1 = Drive not ready, 0 = No Error
  330. ;
  331. ;----------------------------------------------------------------------
  332. CHK_DR  PROC    NEAR
  333.         mov     time_2,T_OVER4
  334.         call    set_time_2              ;15 SEC
  335.         JMP     SHORT   CHK_D2
  336. CHK_DR_INPUT:
  337.         mov     time_2,T_OVER2
  338.         call    set_time_2              ;3 SEC
  339. CHK_D2: CALL    STATUS_COMMAND          ;    READ CD-ROM STATUS
  340.         JZ      CHK_DE                  ;    JUMP IF TIME OUT
  341.         MOV     AL,BYTE PTR STA_CODE    ;    LOAD STATUS
  342.         TEST    AL,DRIVE_READY          ;    TEST DRIVE READY
  343.         JZ      CHK_D1                  ;    JUMP IF DRIVE READY
  344.  
  345.         call    check_time_2
  346.  
  347.         JNZ     CHK_D2                  ;LOOP UNTIL TIME OUT
  348. CHK_DE: RET                             ;TIME OUT ERROR
  349. CHK_D1: INC     AL                      ;CLEAR ZR
  350.         RET
  351. CHK_DR  ENDP
  352. ;------------------------------------------------------------
  353. ; READ ONE DATA BLOCK FROM DRIVE TO CALLER'S DTA
  354. ;
  355. ;       INPUT   MYDTA           Data Transfer Address
  356. ;               CD_MIN  etc.    Data Block Number
  357. ;       OUTPUT  Data in DTA
  358. ;               CY              1 = ECC ERROR, 0 = NO ERROR
  359. ;------------------------------------------------------------
  360. SECREAD PROC    NEAR
  361.         MOV     DI,CS           ;SET BUF_SEGMENT TO ES
  362.         MOV     ES,DI           ;TRANSFER 4 BYTES (ID) TO BUFFER
  363.         LEA     DI,BUF          ;SET BUF_OFFSET TO DI
  364.         CMP     TRNS_MODE,0
  365.         JZ      SECR_SOFT
  366. SECR_3: MOV     CX,4                    ;    SET DMA COUNTER
  367. SECR_1: CALL    DMA                     ;    DMA  CDROM -> BUFFER
  368.         JZ      SECR_E                  ;JUMP IF DMA TIME OUT
  369.         MOV     AX,WORD PTR BUF
  370.         MOV     WORD PTR HEADER,AX
  371.         MOV     AX,WORD PTR BUF+2
  372.         MOV     WORD PTR HEADER+2,AX
  373.         CALL    CHK_ID                  ;CHECK ID
  374.         JZ      SECR_E                  ;    JUMP IF ID ERROR
  375.         MOV     DI,MYDTA_OFF
  376.         MOV     ES,MYDTA_SEG
  377.         CMP     READ_MODE,0
  378.         JE      SECR_2
  379.         PUSH    SI
  380.         MOV     SI,OFFSET RAW_DATA
  381.         MOV     CX,16
  382. ;-------
  383.         MOV     AX,CX
  384.         ADD     AX,DI
  385.         JNC     SECR_1_1
  386.         SUB     CX,AX
  387.         REP     MOVSB
  388.         MOV     CX,ES
  389.         ADD     CX,1000H
  390.         MOV     ES,CX
  391.         MOV     CX,AX
  392.         CMP     CX,0
  393.         JZ      SECR_1_2
  394. SECR_1_1:
  395.         REP     MOVSB
  396. SECR_1_2:
  397.         POP     SI
  398. SECR_2: MOV     CX,2048                 ;TRANSFER DATA TO DTA
  399.         CMP     READ_MODE,0
  400.         JE      SECR_4
  401.         MOV     CX,2048+288
  402. SECR_4:
  403.         CALL    DMA                     ;    DMA  CD-ROM -> DTA
  404.         JNE     SECR_DEND_END
  405. SECR_E:
  406.         RET
  407. ;--------< SOFT READ >------------
  408. SECR_SOFT:
  409.         CALL    SECR_4B
  410. SECR_S_4:
  411.         MOV     AX,WORD PTR BUF
  412.         MOV     WORD PTR HEADER,AX
  413.         MOV     AX,WORD PTR BUF+2
  414.         MOV     WORD PTR HEADER+2,AX
  415.         CALL    CHK_ID                  ;CHECK ID
  416.         JZ      SECR_E                  ;    JUMP IF ID ERROR
  417.         MOV     DI,MYDTA_OFF
  418.         MOV     ES,MYDTA_SEG
  419.         CMP     READ_MODE,0
  420.         JE      SECR_S_4_3
  421.         PUSH    SI
  422.         MOV     SI,OFFSET RAW_DATA
  423.         MOV     CX,16
  424. ;-------
  425.         MOV     AX,CX
  426.         ADD     AX,DI
  427.         JNC     SECR_S_4_1
  428.         SUB     CX,AX
  429.         REP     MOVSB
  430.         MOV     CX,ES
  431.         ADD     CX,1000H
  432.         MOV     ES,CX
  433.         MOV     CX,AX
  434.         CMP     CX,0
  435.         JZ      SECR_S_4_2
  436. SECR_S_4_1:
  437.         REP     MOVSB
  438. SECR_S_4_2:
  439.         POP     SI
  440. SECR_S_4_3:
  441.         CMP     CPU_MODE,2
  442.         JE      SECR_S_5
  443.         CALL    BOUND_CHECK             ;<1>
  444.         CMP     READ_MODE,0
  445.         JNE     SECR_S_4_4
  446.         CALL    NDMA_88_2048
  447.         JMP     SHORT SECR_DEND_END
  448. SECR_S_4_4:
  449.         CALL    NDMA_88_2336
  450. SECR_DEND_END:
  451.         MOV     AH,50
  452.         JMP     SHORT DEND_PROC_1
  453. SECR_S_5:
  454.         MOV     CX,2048
  455.         CMP     READ_MODE,0
  456.         JE      SECR_S_5_1
  457.         MOV     CX,2048+288
  458. SECR_S_5_1:
  459.         CALL    INSB_LOOP_ENT_SUB
  460.         MOV     AH,120                  ;DEND PROCEDURE
  461. DEND_PROC_1:
  462.         PPI_PC                          ;CHANGE DRIVE TO COMMAND MODE
  463.         MOV     AL,DEND_IN              ;    LOAD DEND CODE
  464.         OR      AL,DRIVE_NO_MASK        ;SET DRIVE SELECT
  465.         OUT     DX,AL                   ;    SET DEND
  466. SECR_S_DEND:
  467.         DEC     AH
  468.         JNZ     SECR_S_DEND
  469.         MOV     AL,CLR_IN               ;    LOAD DEND RESET CODE
  470.         OR      AL,DRIVE_NO_MASK        ;SET DRIVE SELECT
  471.         OUT     DX,AL                   ;    RESET DEND, RESET ZR
  472.         RET
  473.  
  474. SECR_4B:                                ;READ 4 BYTES (HEADER)
  475.         DATA_PORT
  476.         MOV     CX,4                    ;READ HEADER ( 4 bytes )
  477.         CMP     CPU_MODE,2
  478.         JE      SECR_S_3                ;80286
  479.         CALL    BOUND_CHECK             ;<1>
  480. SECR_S_2:
  481.         IN      AL,DX
  482.         STOSB
  483.         JMP     SHORT $+2
  484.         JMP     SHORT $+2
  485.         LOOP    SECR_S_2
  486.         RET
  487. SECR_S_3:
  488.         CALL    INSB_LOOP_ENT_SUB ;<1>
  489.         RET
  490.  
  491. BOUND_CHECK:
  492.         PUSH    AX
  493.         MOV     AX,2340
  494.         ADD     AX,DI
  495.         JNC     BOUND_RET
  496.         MOV     AX,ES
  497.         ADD     AX,100H         ;+4096
  498.         MOV     ES,AX
  499.         SUB     DI,1000H
  500. BOUND_RET:
  501.         POP     AX
  502.         RET
  503. SECREAD ENDP
  504.  
  505. ;----------------------------------------------------------------------
  506. ; READ ONE DATA BLOCK TO BUFFER AND CORRECT
  507. ;
  508. ;       INPUT   MYDTA           Data Transfer Address
  509. ;               CD_MIN  etc.    Data Block Number
  510. ;       OUTPUT  Data in DTA
  511. ;               CY              1 = ECC ERROR, 0 = NO ERROR
  512. ;               ZR              1 = Time Out Error, 0 = No Error
  513. ;
  514. ;----------------------------------------------------------------------
  515. ER_CORRECT      PROC    NEAR
  516.         MOV     DI,CS                   ;TRANSFER ALL DATA OF THE BLOCK TO BUFFER
  517.         MOV     ES,DI                   ;    LOAD SEGMENT IN ES
  518.         LEA     DI,BUF                  ;    LOAD OFFSET  IN DI
  519.         CMP     TRNS_MODE,0
  520.         JNE     ER_COR_1
  521.         JMP     ER_SOFT         ;JE     ER_SOFT
  522. ER_COR_1:
  523.         MOV     CX,2340                 ;    SET 4+2048+288  IN CX
  524.         CALL    DMA                     ;    DMA  CD-ROM -> BUFFER
  525.         JNZ     ECC_CHK
  526.         JMP     ERC_E1          ;JZ     ERC_E1                  ;JUMP IF DMA TIME OUT
  527.  
  528. ECC_CHK:
  529.         MOV     BYTE PTR PAUSE_FLG,0FFH ;SET PAUSE FLUG
  530.         CALL    PAUSE_COMMAND           ;ISSUE PAUSE COMMAND
  531.         JZ      ERC_E1                  ;JUMP IF COMMAND FAILED
  532.         CALL    ECC                     ;ECC DECODE
  533.  
  534. ;----------------------------------------------------------------------
  535. ; ECC is a subroutine which corrects the data errors of the CD_ROM. 
  536. ; Almost all data errors should have been corrected by CDR-1502S's data
  537. ; processing LSI using CD's error correct code ( Ccross Interleave
  538. ; Reed-Solomon Code ) and this subroutine may not be necessary. But if
  539. ; there are some fatal defects on the disc and some errors cannot be
  540. ; corrected by data processing LSI, they may be corrected with ECC
  541. ; routine using additional Layered Error Correct Code.  Object module
  542. ; of ECC is stored in ECC.OBJ.  Please link ECC.OBJ and CDREAD.OBJ
  543. ; together with your software when you use them.
  544. ;----------------------------------------------------------------------
  545. ; ECC   INPUT   Data in BUF
  546. ;                       ID             4  Bytes
  547. ;                       Data        2048  Bytes
  548. ;                       Layered ECC  288  Bytes
  549. ;       OUTPUT          Corrected Data in BUF
  550. ;                       CY      1 = ECC Error, 0 = No Error
  551. ;----------------------------------------------------------------------
  552.         MOV     CX,CS
  553.         MOV     DS,CX
  554.         JC      ERC_E2                  ;JUMP IF ECC FAILED
  555.         MOV     AX,WORD PTR BUF
  556.         MOV     WORD PTR HEADER,AX
  557.         MOV     AX,WORD PTR BUF+2
  558.         MOV     WORD PTR HEADER+2,AX
  559.         CALL    CHK_ID                  ;CHECK ID
  560.         JZ      ERC_E1                  ;JUMP IF ID ERROR
  561.         MOV     CX,CS
  562.         MOV     DS,CX
  563.         MOV     ES,MYDTA_SEG            ;    LOAD  ES:DTA_SEGMENT
  564.         MOV     DI,MYDTA_OFF            ;    LOAD  DI:DTA_OFFSET
  565.         CMP     READ_MODE,0
  566.         JE      ECC_S_4_3
  567.         PUSH    SI
  568.         MOV     SI,OFFSET RAW_DATA
  569.         MOV     CX,16
  570. ;-------
  571.         MOV     AX,CX
  572.         ADD     AX,DI
  573.         JNC     ECC_S_4_1
  574.         SUB     CX,AX
  575.         REP     MOVSB
  576.         MOV     CX,ES
  577.         ADD     CX,1000H
  578.         MOV     ES,CX
  579.         MOV     CX,AX
  580.         CMP     CX,0
  581.         JZ      ECC_S_4_2
  582. ECC_S_4_1:
  583.         REP     MOVSB
  584. ECC_S_4_2:
  585.         POP     SI
  586. ECC_S_4_3:
  587.         MOV     SI,OFFSET BUF+4         ;    LOAD  SI:BUF+4_OFFSET
  588.         MOV     CX,2048                 ;    LOAD  CX:2048
  589.         CMP     READ_MODE,0
  590.         JE      ECC_S_4_4
  591.         MOV     CX,2048+288
  592. ECC_S_4_4:
  593. ;
  594.         MOV     AX,CX
  595.         ADD     AX,DI
  596.         JNC     ER_COR_2
  597.         SUB     CX,AX
  598.         REP     MOVSB
  599.         MOV     CX,ES
  600.         ADD     CX,1000H
  601.         MOV     ES,CX
  602.         MOV     CX,AX
  603.         CMP     CX,0
  604.         JZ      ER_COR_3
  605. ;
  606. ER_COR_2:
  607.         REP     MOVSB                   ;SOFTWARE TRANSFER
  608. ER_COR_3:
  609.         OR      AL,1                    ;CLEAR ZR - OK
  610. ERC_E1: CLC                             ;CLEAR CY
  611. ERC_E2: RET
  612. ER_SOFT:
  613.         CMP     CPU_MODE,2
  614.         JE      ER_SOFT_1
  615.         CALL    BOUND_CHECK
  616.         CALL    SECR_4B         ;READ 4 B
  617. ;
  618.         CALL    NDMA_88_2336
  619.         JMP     ECC_CHK
  620. ER_SOFT_1:
  621.         MOV     CX,2340
  622.         CALL    INSB_LOOP_ENT_SUB
  623.         JMP     ECC_CHK
  624. ER_CORRECT      ENDP
  625.  
  626.  
  627.  
  628. INSB_LOOP_ENT_SUB proc near
  629.         MOV     AX,CX
  630.         ADD     AX,DI
  631.         JNC     INSB_L_SUB_1
  632.         SUB     CX,AX
  633.         CALL    INSB_LOOP_ENT
  634.         MOV     CX,ES
  635.         ADD     CX,1000H
  636.         MOV     ES,CX
  637.         MOV     CX,AX
  638.         CMP     CX,0
  639.         JZ      INSB_L_SUB_2
  640. INSB_L_SUB_1:
  641.         CALL    INSB_LOOP_ENT
  642. INSB_L_SUB_2:
  643.         OR      AL,1
  644.         CLC
  645.         RET
  646. INSB_LOOP_ENT_SUB endp
  647.  
  648.  
  649. NDMA_88_2048:
  650.         MOV     CX,64
  651.         JMP     SHORT NDMA_88_1
  652. NDMA_88_2336:
  653.         MOV     CX,73
  654. NDMA_88_1:
  655.         MOV     AL,CLOCK_COUNT
  656.         CMP     AL,1
  657.         JBE     INSB_LOOP_ENT
  658.         SHL     CX,1            ;CX * 2 
  659.         CMP     AL,3
  660.         JBE     INSB_LOOP_ENT
  661.         SHL     CX,1
  662.         SHL     CX,1
  663.         SHL     CX,1
  664.         SHL     CX,1            ;CX * 16
  665.  
  666. INSB_LOOP_ENT:
  667.         DATA_PORT
  668.         EVEN
  669. INSB_LOOP:
  670.         IN      AL,DX
  671.         STOSB
  672.         DB      126 DUP(90H)    ;NOP
  673.         RET
  674.  
  675. ;
  676. ; far entry point to INSB_LOOP_ENT from _LAST segment
  677. ;
  678. _INSB_LOOP_ENT proc far
  679.         call    INSB_LOOP_ENT
  680.         ret
  681. _INSB_LOOP_ENT endp
  682.  
  683. ;----------------------------------------------------------------------
  684. ; COMMAND PROCEDURES
  685. ;----------------------------------------------------------------------
  686. COMMAND PROC    NEAR
  687. AUDIO_TNO_COMMAND:
  688.         MOV     AL,AL_SAVE
  689.         OR      AL,COMAUDIO_TNO
  690.         MOV     COM,AL
  691.         MOV     AL,CD_MIN
  692.         MOV     BYTE PTR COM+1,AL
  693.         MOV     AL,CD_SEC
  694.         MOV     BYTE PTR COM+2,AL
  695.         MOV     SI,OFFSET COM+1
  696.         MOV     DI,SI
  697.         MOV     CX,CS
  698.         MOV     ES,CX
  699.         MOV     CX,2
  700.         CALL    BCD_S
  701.         MOV     CX,4
  702.         JMP     COMEN
  703. CH_CTRL_COMMAND:
  704.         MOV     AL,AL_SAVE
  705.         OR      AL,0D0H
  706.         MOV     COM,AL
  707.         JMP     COMMAND_1B
  708. STOP_COMMAND:
  709.         MOV     COM,COMSTOP
  710.         JMP     COMMAND_1B
  711. OPEN_COMMAND:
  712.         MOV     WORD PTR COM,COMOPEN
  713.         JMP     SHORT COMMAND_2B
  714. CLOSE_COMMAND:
  715.         MOV     WORD PTR COM,COMCLOSE
  716. COMMAND_2B:
  717.         MOV     CX,3
  718.         JMP     short COMEN
  719.  
  720. SET_POWER_COMMAND:
  721.         MOV     COM,COMPOWER
  722.         MOV     AL,AL_SAVE
  723.         MOV     BYTE PTR COM+1,AL
  724.         MOV     SI,OFFSET COM+1
  725.         MOV     DI,SI
  726.         MOV     CX,CS
  727.         MOV     ES,CX
  728.         MOV     CX,1
  729.         CALL    BCD_S
  730.         MOV     CX,3
  731.         JMP     short COMEN
  732. AUDIO_COMMAND:
  733.         MOV     DI,OFFSET COM+1
  734.         MOV     SI,MYDTA_OFF
  735.         MOV     DS,MYDTA_SEG
  736.         MOV     CX,CS
  737.         MOV     ES,CX
  738.         MOV     CX,6
  739.         REP     MOVSB
  740.         MOV     CX,CS
  741.         MOV     DS,CX
  742.         MOV     AL,AL_SAVE
  743.         OR      AL,COMAUDIO
  744.         MOV     COM,AL
  745.         MOV     CX,6
  746.         MOV     SI,OFFSET COM+1
  747.         MOV     DI,SI
  748.         CALL    BCD_S
  749.         MOV     CX,8
  750.         JMP     short COMEN
  751. READ_COMMAND:                           ;ISSUE READ COMMAND
  752.         MOV     BYTE PTR COM,COMREAD    ;    SET READ COMMAND
  753. COMMAND_4B:
  754.         CALL    BCD                     ;    CONVERT DATA BLOCK NUMBER TO BCD CODE
  755. COMMAND_4B_1:
  756.         MOV     CX,5                    ;    SET COUNTER 4 + 1 (C.C.C.)
  757.         JMP     SHORT COMEN             ;JUMP TO COMMON ENTRY POINT
  758. SEEK_COMMAND:                           ;ISSUE SEEK COMMAND
  759.         MOV     BYTE PTR COM,COMSEEK    ;    SET SEEK COMMAND
  760.         JMP     SHORT COMMAND_4B        ;JUMP TO COMMAND_4B
  761. PAUSE_COMMAND:                          ;ISSUE PAUSE COMMAND
  762.         MOV     BYTE PTR COM,COMPAUSE   ;    SET PAUSE COMMAND
  763.         JMP     SHORT COMMAND_1B        ;JUMP TO COMMAND_1B
  764. SEEK_LEAD_COMMAND:
  765.         MOV     BYTE PTR COM,COMLEADIN
  766.         JMP     SHORT COMMAND_1B
  767. RESET_COMMAND:                          ;ISSUE RESET COMMAND
  768.         MOV     BYTE PTR COM,COMRESET   ;    SET RESET COMMAND
  769. COMMAND_1B:
  770.         MOV     CX,2                    ;    SET COUNTER 1 + 1 (C.C.C.)
  771.         JMP     SHORT COMEN             ;JUMP TO COMMAND ROUTINE
  772. ;----------------------------------------------------------------------
  773. ; OUTPUT COMMAND TO DRIVE
  774. ;
  775. ;       INPUT   CX              COMMAND LENGTH + 1
  776. ;               CS:COM          COMMAND CODE
  777. ;               CS:COM+1        MINUTE     (BCD)
  778. ;               CS:COM+2        SECOND       "
  779. ;               CS:COM+3        DATA BLOCK   "
  780. ;       OUTPUT  ZF              1 = TIME OUT ERROR, 0 = NO ERROR
  781. ;----------------------------------------------------------------------
  782. COMEN:
  783.         MOV     GENERAL_FLAG,0
  784. COMEN_SUB:
  785.  
  786.         LEA     SI,BUF
  787.  
  788.         CMP     GENERAL_FLAG,1
  789.         JE      COMEN_SUB_1
  790.         LEA     SI,BYTE PTR COMC        ;OUTPUT C.C.C AND COMMAND CODES
  791.         CMP     CX,1
  792.         JNZ     COMEN_SUB_1
  793.         LEA     SI,BYTE PTR COM         ;OUTPUT COMMAND CODES
  794. COMEN_SUB_1:
  795.         MOV     BL,DRIVE_NO_MASK
  796.         CALL    COM_END_SUB
  797.         IN_PB
  798.         TEST    AL,BUS_BUSY             ;    IS BUS BUSY(DMA MODE)?
  799.         JZ      COM_1                   ;    JUMP IF BUS IS READY(COMMAND MODE)
  800.         INC     DX                      ;    PPI_PC
  801.         MOV     AL,DEND_IN              ;    LOAD DEND CODE
  802.         OR      AL,BL
  803.         OUT     DX,AL                   ;    SET DEND
  804.         mov     time_1,T_OVER1
  805.         call    set_time_1              ;SET 1 SEC
  806. COM_2:  IN_PB
  807.         TEST    AL,BUS_BUSY             ;        CHECK BUS_BUSY
  808.         JZ      COM_6                   ;        JUMP IF CDROM IS READY
  809.  
  810.         call    check_time_1
  811.  
  812.         JNZ     COM_2                   ;    LOOP UNTIL BUS_BUSY RESET
  813.         JMP     short COM_E             ;        JUMP IF TIME OUT
  814. COM_6:  INC     DX                      ;NOW CDROM IS READY, RESET DEND
  815.         MOV     AL,CLR_IN               ;    LOAD DEND RESET CODE
  816.         OR      AL,BL
  817.         OUT     DX,AL                   ;    RESET DEND
  818. COM_1:
  819.         mov     time_1,T_OVER1
  820.         call    set_time_1              ;SET 1 SEC
  821. COM_1_1:
  822.  
  823.         call    check_time_1
  824.         jnz     @f
  825.         jmp     short COM_E
  826. @@:
  827. ;       JZ      COM_E                   ;        JUMP IF TIME OUT
  828.         IN_PB
  829.         TEST    AL,ACK                  ;        TEST ACK
  830.         JNZ     COM_1_1                 ;    LOOP UNTIL ACK OFF
  831. COM_1_2:
  832.         PPI_CR                          ;SET PPI_PA OUTPUT MODE
  833.         MOV     AL,PAOUT                ;
  834.         OUT     DX,AL                   ;    PPI_CR <- PAOUT
  835.         DEC     DX                      ;PPI_PC
  836.         MOV     AL,CLR_OUT              ;    LOAD BUS DIR OUT CODE
  837.         OR      AL,BL
  838.         JMP     $+2
  839.         OUT     DX,AL                   ;    BUS_DIR OUT
  840. COM_4:
  841.         PPI_PA
  842.         LODSB
  843.         OUT     DX,AL                   ;    OUTPUT COMMAND CODE
  844.         CMP     IF_FLAG,1
  845.         JNE     COM_4_1
  846.         DATA_PORT
  847.         MOV     AL,0FFH
  848.         OUT     DX,AL
  849. COM_4_1:
  850.         PPI_PC
  851.         MOV     AL,CMD_OUT
  852.         OR      AL,BL
  853.         OUT     DX,AL
  854.  
  855.         mov     time_1,T_OVER1
  856.         call    set_time_1              ;SET 1 SEC
  857. COM_3:
  858.  
  859.         call    check_time_1
  860.  
  861.         JZ      COM_E                   ;        JUMP IF TIME OUT
  862.         IN_PB                           ;        LOAD ACK
  863.         TEST    AL,ACK                  ;        TEST ACK
  864.         JZ      COM_3
  865. COM_7:  MOV     AL,CLR_OUT              ;    RESET CMD
  866.         OR      AL,BL
  867.         INC     DX                      ;PPI_PC
  868.         OUT     DX,AL                   ;
  869.         mov     time_1,T_OVER1
  870.         call    set_time_1              ;SET 1 SEC
  871. COM_5:
  872.  
  873.         call    check_time_1
  874.  
  875.         JZ      COM_E                   ;        JUMP IF TIME OUT
  876.         IN_PB                           ;        LOAD ACK
  877.         TEST    AL,ACK                  ;        TEST ACK
  878.         JNZ     COM_5                   ;    LOOP UNTIL ACK OFF
  879. COM_8:
  880.         LOOP    fix_this_mike                   ;LOOP UNTIL ALL COMMAND CODES HAVE BEEN SENT
  881.         OR      DX,1                    ;RESET ZR
  882. COM_E:
  883.         PUSHF
  884.         CALL    COM_END_SUB
  885.         POPF
  886.         RET
  887.  
  888. fix_this_mike:
  889.         jmp     COM_4
  890.  
  891. IN_PB_SUB:
  892.         MOV     DX,BP
  893. IN_PB_1:
  894.         IN      AL,DX                   ;LOAD PPI PORT_B
  895.         AND     AL,03H                  ;MASK RESERVED BITS
  896.         RET
  897. COM_END_SUB:
  898.         PPI_CR                          ;SET PPI PORT_A INPUT MODE
  899.         MOV     AL,PAIN                 ;
  900.         OUT     DX,AL                   ;    PPI_CR <- PAIN
  901.         DEC     DX                      ;PPI_PC
  902.         MOV     AL,CLR_IN               ;    LOAD CLEAR & BUS_DIR IN CODE
  903.         OR      AL,BL
  904.         JMP     $+2
  905.         OUT     DX,AL                   ;    CLEAR & BUS_DIR IN
  906.         RET
  907. COMMAND ENDP
  908. ;----------------------------------------------------------------------
  909. ; STATUS READ PROCEDURES
  910. ;----------------------------------------------------------------------
  911. COMSTATUS       PROC    NEAR            ;STATUS READ
  912. GENERAL_COMMAND:
  913.         MOV     CL,AL_SAVE
  914.         XOR     CH,CH
  915.         CMP     CL,0
  916.         JNE     GENERAL_COM_1
  917.         JMP     COMST_END
  918. GENERAL_COM_1:
  919.         LEA     DI,BUF+1
  920.         PUSH    CX
  921.         MOV     SI,SI_SAVE
  922.         INC     SI
  923.         INC     SI                      ;POINT AT HEAD OF SEND-DATA
  924.         MOV     AX,DI_SAVE
  925.         MOV     DS,AX
  926.         MOV     AX,CS
  927.         MOV     ES,AX
  928.         REP     MOVSB
  929.         MOV     AX,CS
  930.         MOV     DS,AX
  931.         MOV     BYTE PTR BUF,0FFH
  932.         MOV     GENERAL_FLAG,1
  933.         POP     CX
  934.         INC     CX
  935.         CALL    COMEN_SUB
  936.         JNZ     GENERAL_COM_2
  937.         JMP     COMST_END
  938. GENERAL_COM_2:
  939.         MOV     CH,CH_SAVE
  940.         MOV     CL,CL_SAVE
  941.         MOV     COM_COUNT,CX
  942.         CMP     CX,0
  943.         JNZ     GENERAL_COM_3
  944.         JMP     COMST_END
  945. GENERAL_COM_3:
  946.         JMP     READ_SUB
  947.  
  948.  
  949. ;
  950. ; far entry point to STATUS_COMMAND from _LAST segment
  951. ;
  952. _STATUS_COMMAND proc far
  953.         call    STATUS_COMMAND
  954.         ret
  955. _STATUS_COMMAND endp
  956.  
  957.  
  958. STATUS_COMMAND:                         ;ISSUE STATUS COMMAND
  959.         MOV     COM,COMST               ;    SET STATUS COMMAND
  960.         JMP     SHORT STATUS_1
  961. DSKSTA_COMMAND:                         ;ISSUE DISK_STATUS COMMAND
  962.         MOV     COM,COMDSKST            ;    SET DISK_STATUS COMMAND
  963.         JMP     SHORT STATUS_1
  964. P_A_MED_COMMAND:
  965.         MOV     COM,COMLOCK
  966.         CMP     AL_SAVE,0
  967.         JZ      STATUS_1
  968.         OR      COM,08H
  969.         CMP     AL_SAVE,2
  970.         JZ      STATUS_1
  971.         OR      COM,01H
  972. STATUS_1:
  973.         MOV     CX,1                    ;    SET COMMAND COUNTER
  974.         CALL    COMEN                   ;    OUTPUT C.C.C. & STATUS COMMAND
  975.         JZ      COMST_END_1             ;JUMP IF COMMAND ERROR
  976.         MOV     WORD PTR COM_COUNT,1
  977.         MOV     DI,CS
  978.         MOV     ES,DI
  979.         MOV     DI,OFFSET STA_CODE
  980.         JMP     short STATUS_LOOP
  981. READ_SUBQ_COMMAND:
  982.         MOV     COM,COMSUBQ             ;READ SUBCODE Q COMMAND
  983.         MOV     CX,1
  984.         CALL    COMEN
  985.         JZ      COMST_END_1
  986. READ_SUB_C_1:
  987.         MOV     WORD PTR COM_COUNT,10
  988.         JMP     SHORT READ_SUB
  989. READ_PORT_COMMAND:
  990.         MOV     WORD PTR COM,COMPORT_1
  991.         MOV     WORD PTR COM+2,COMPORT_2
  992.         MOV     CX,5
  993.         CALL    COMEN
  994.         JZ      COMST_END_1
  995.         MOV     WORD PTR COM_COUNT,30
  996.         JMP     SHORT READ_SUB
  997. UCOM_COMMAND:
  998.         MOV     BYTE PTR COM,30H
  999.         MOV     BYTE PTR COM+1,90H
  1000.         MOV     BYTE PTR COM+2,90H
  1001.         MOV     BYTE PTR COM+3,82H
  1002.         MOV     CX,5
  1003.         CALL    COMEN
  1004.         JZ      COMST_END_1
  1005.         MOV     WORD PTR COM_COUNT,192
  1006.         JMP     SHORT READ_SUB
  1007. VERSION_COMMAND:
  1008.         MOV     WORD PTR COM,COMID_1
  1009.         MOV     WORD PTR COM+2,COMID_2
  1010.         MOV     CX,5
  1011.         CALL    COMEN
  1012.         JNZ     VERSION_1_COM
  1013. COMST_END_1:
  1014.         JMP     short COMST_END
  1015. VERSION_1_COM:
  1016.         MOV     WORD PTR COM_COUNT,52
  1017.  
  1018. READ_SUB:
  1019.         MOV     DI,WORD PTR MYDTA_OFF
  1020.         MOV     ES,WORD PTR MYDTA_SEG
  1021. ;----------------------------------------------------------------------
  1022. ; READ CD-ROM STATUS
  1023. ;
  1024. ;       INPUT   ES:DI
  1025. ;               COM_COUNT
  1026. ;       OUTPUT  ES:DI   DATA FROM CD_ROM
  1027. ;               ZR              1 = TIME OUT ERROR, 0 = NO ERROR
  1028. ;----------------------------------------------------------------------
  1029. STATUS_LOOP:
  1030.         MOV     BL,CS:DRIVE_NO_MASK
  1031.         PPI_PC
  1032.         MOV     AL,CMD_IN               ;    LOAD SET CMD CODE
  1033.         OR      AL,BL
  1034.         OUT     DX,AL                   ;    SET CMD
  1035.         mov     time_1,T_OVER1
  1036.         call    set_time_1              ;SET 1 SEC
  1037.         EVEN
  1038. COMST_3:
  1039.  
  1040.         call    check_time_1
  1041.  
  1042.         JZ      COMST_END               ;    JUMP IF TIME OUT ERROR
  1043.         IN_PB                           ;    READ PPI_PB
  1044.         TEST    AL,ACK                  ;    TEST ACK
  1045.         JZ      COMST_3                 ;LOOP UNTIL ACK ON
  1046.         PPI_PA
  1047.         IN      AL,DX                   ;    READ PPI_PA
  1048.         NOP
  1049.         STOSB
  1050.         PPI_PC
  1051.         MOV     AL,CLR_IN               ;    LOAD CMD RESET CODE
  1052.         NOP
  1053.         OR      AL,BL
  1054.         OUT     DX,AL                   ;    RESET CMD
  1055.         mov     time_1,T_OVER1
  1056.         call    set_time_1              ;SET 1 SEC
  1057. COMST_5:
  1058.  
  1059.         call    check_time_1
  1060.  
  1061.         JZ      COMST_END               ;    JUMP IF TIME OUT ERROR
  1062.         IN_PB
  1063.         TEST    AL,ACK                  ;    TEST ACK
  1064.         JNZ     COMST_5                 ;IF ACK IS ON,THEN WAIT AGAIN
  1065.         DEC     WORD PTR COM_COUNT
  1066.         JZ      COM_ST_NRT              ;NORMAL RETURN
  1067.         JMP     STATUS_LOOP
  1068. COM_ST_NRT:
  1069.         AND     DX,DX                   ;RESET ZR
  1070. COMST_END:
  1071.         PUSHF
  1072.         CALL    COM_END_SUB
  1073.         POPF
  1074.         RET
  1075. COMSTATUS       ENDP
  1076. ;----------------------------------------------------------------------
  1077. ; DMA PROCEDURE
  1078. ;       INPUT   ES:SEGMENT OF DATA TRANSFER ADDRESS
  1079. ;               DI:OFFSET  "    "      "       "
  1080. ;               CX:TRANSFER COUNT
  1081. ;       OUTPUT  ZR              1 = DMA TIME OUT ERROR, 0 = NO ERROR
  1082. ;----------------------------------------------------------------------
  1083. DMA     PROC    NEAR
  1084.         MOV     AX,DI                   ;CALCULATE PAGE AND TRANSFER ADDRESS
  1085.         MOV     DX,AX                   ;    AX,DX  <-  OFFSET
  1086.         MOV     BX,ES                   ;    BX     <-  SEGMENT
  1087.         SHR     AX,1                    ;    DIVIDE AX BY 16
  1088.         SHR     AX,1
  1089.         SHR     AX,1
  1090.         SHR     AX,1
  1091.         ADD     AX,BX                   ;    GET TOTAL ADDRESS EXCEPT LOWER 4 BYTES
  1092.         MOV     BX,AX                   ;    STORE IT IN BX
  1093.         AND     AX,0F000H               ;    GET PAGE ADDRESS IN AX
  1094.         SHR     AX,1                    ;        DIVIDE BY 16
  1095.         SHR     AX,1
  1096.         SHR     AX,1
  1097.         SHR     AX,1
  1098.         AND     DX,000FH                ;    GET TRANSFER ADDRESS
  1099.         SHL     BX,1                    ;        MULTIPLY BX BY 16
  1100.         SHL     BX,1
  1101.         SHL     BX,1
  1102.         SHL     BX,1
  1103.         ADD     BX,DX                   ;        ADD TOTAL ADDRESS LOWER 4 BYTES
  1104.         MOV     DX,BX                   ;    STORE IT IN DX
  1105.         DEC     BX                      ;CHECK PAGE ADDRESS SHOULD BE UPDATED OR NOT
  1106.         ADD     BX,CX                   ;    CALCULATE LAST TRANSFER ADDRESS
  1107.         JC      DMA_1                   ;    IF CARRY = 1, THEN PAGE ADDRESS WILL BE UPDATED
  1108. DMA_2:  CALL    DMA_SUB                 ;PAGE ADDRESS DOES NOT CHANGE, DMA IN BEGINNING PAGE
  1109. DMA_3:  RET                             ;DMA END
  1110. DMA_1:  AND     DX,DX                   ;CHECK TRANSFER ADDRESS = 0
  1111.         JZ      DMA_2                   ;    IF TRANSFER ADDRESS IS 0, PAGE ADDRESS NEVER CHANGES
  1112.         ADD     BX,01H                  ;GET COUNT IN NEXT PAGE
  1113.         SUB     CX,BX                   ;GET COUNT WITHIN BEGINNING PAGE
  1114.         PUSH    AX                      ;SAVE PAGE ADDRESS
  1115.         PUSH    BX                      ;SAVE COUNT OF NEXT PAGE
  1116.         CALL    DMA_SUB                 ;DMA WITHIN BEGINNING PAGE
  1117.         POP     CX                      ;RESTORE COUNT OF NEXT PAGE
  1118.         POP     AX                      ;RESTORE PAGE ADDRESS
  1119.         JZ      DMA_3                   ;JUMP IF DMA ERROR HAPPENED
  1120.         INC     AH                      ;DMA IN NEXT PAGE    UPDATE PAGE ADDRESS
  1121.         XOR     DX,DX                   ;    CLEAR TRANSFER ADDRESS
  1122.         JMP     SHORT DMA_2             ;    DMA TRANSFER AGAIN IN NEXT PAGE
  1123. DMA     ENDP
  1124. ;----------------------------------------------------------------------
  1125. ; DMA_SUB PROCEDURE
  1126. ;       INPUT   AH              PAGE ADDRESS
  1127. ;               CX              TRANSFER COUNT
  1128. ;               DX              TRANSFER ADDRESS
  1129. ;       OUTPUT  ZR              1 = DMA TIME OUT ERROR, 0 = NO ERROR
  1130. ;
  1131. ;----------------------------------------------------------------------
  1132. DMA_SUB PROC    NEAR                    ;
  1133.         CLI                             ;MASK INTERRUPT
  1134.         OUT     DMAC_CLR,AL             ;CLEAR FIRST/LAST FLAG
  1135.         JMP     SHORT $+2
  1136.         IN      AL,DMAC_STA             ;DUMMY READ  ---  CLEAR CT FLAG OF DMAC
  1137.         MOV     AL,DMACOM               ;SET DMAC COMMAND REGISTER
  1138.         JMP     $+2
  1139.         OUT     DMAC_COM,AL             ;
  1140.         MOV     AL,DMAMODE              ;SET DMAC MODE REGISTER
  1141.         JMP     $+2
  1142.         OUT     DMAC_MODE,AL            ;
  1143.         MOV     AL,AH                   ;
  1144.         JMP     SHORT $+2
  1145.         OUT     DMAC_PAGE,AL            ;SET PAGE REGISTER
  1146.         MOV     AL,DL                   ;
  1147.         JMP     SHORT $+2
  1148.         OUT     DMAC_AD,AL              ;SET DMAC ADDRESS REG.
  1149.         MOV     AL,DH                   ;
  1150.         JMP     SHORT $+2
  1151.         OUT     DMAC_AD,AL              ;          "
  1152.         DEC     CX                      ;SET TERMINAL COUNT
  1153.         MOV     AL,CL                   ;       TOTAL COUNT - 1
  1154.         JMP     SHORT $+2
  1155.         OUT     DMAC_TC,AL              ;SET DMAC TERMINAL COUNT REG.
  1156.         MOV     AL,CH                   ;
  1157.         JMP     SHORT $+2
  1158.         OUT     DMAC_TC,AL              ;           "
  1159.         STI                             ;ENABLE INTERRUPT
  1160.         PPI_PC
  1161.         MOV     AL,DMAE_IN              ;    AL <- 80H
  1162.         OR      AL,DRIVE_NO_MASK
  1163.         OUT     DX,AL                   ;    PPI_PC <- AL
  1164.         MOV     AL,DMAENA               ;SET DMA CH3 ENABLE
  1165.         OUT     DMAC_MSK,AL             ;       "
  1166.         XOR     BX,BX
  1167. DMA_S1: IN      AL,DMAC_STA             ;CHECK DMA TERMITATE
  1168.         TEST    AL,08H                  ;    TEST TERMINAL COUNT FLAG
  1169.         JNZ     DMA_S2                  ;    JUMP IF DMA TERMINATED
  1170.         DEC     BX                      ;    DECREMENT TIMER
  1171.         JZ      DMA_SE                  ;    JUMP IF TIME OUT ERROR
  1172.         JMP     DMA_S1                  ;WAIT UNTIL DMA TERMINATE
  1173. DMA_S2: MOV     AL,CLR_IN               ;DMA TERNINATED NORMALLY
  1174.         PUSHF
  1175.         OR      AL,DRIVE_NO_MASK
  1176.         POPF
  1177.         OUT     DX,AL                   ;    DISABLE DMA
  1178.         RET                             ;DMA END
  1179. DMA_SE: MOV     AL,DMADIS               ;DMA TIME OUT ERROR
  1180.         OUT     DMAC_MSK,AL             ;    DISABLE DMAC
  1181.         JMP     DMA_S2                  ;
  1182. DMA_SUB ENDP
  1183.                 PAGE
  1184. ;--------------------------------------
  1185. ;       M A I N   R O U T I N E
  1186. ;--------------------------------------
  1187. START:
  1188.         CLD
  1189.         PUSH    DS                      ;PRESERVE REGISTERS
  1190.         PUSH    ES
  1191.         PUSH    BP
  1192.         PUSH    BX
  1193.         PUSH    CX
  1194.         PUSH    DX
  1195.         PUSH    DI
  1196.         PUSH    SI
  1197.  
  1198.         PUSH    CS                      ;SET DS = CS
  1199.         POP     DS
  1200.         CALL    IN_SAVE                 ;SAVE PARAMETERS
  1201.         MOV     BP,WORD PTR CURRENT_IF
  1202.         INC     BP                      ;POINT AT PPI_PB
  1203.         MOV     BYTE PTR STA_CODE,0
  1204.         MOV     BYTE PTR READ_MODE,0    ;2048 mode
  1205. START_EXT_0:
  1206.         CMP     AH_SAVE,19H
  1207.         JNE     START_EXT_2
  1208.         MOV     AX,SI_SAVE
  1209.         CMP     AH,19H
  1210.         JNE     START_EXT_1
  1211.         JMP     COM_ER
  1212. START_EXT_1:                            ;EXTENDED COMMAND
  1213.         MOV     AH_SAVE,AH
  1214.         MOV     AL_SAVE,AL
  1215. START_EXT_2:
  1216.         CMP     AH_SAVE,1AH
  1217.         JNE     START_0
  1218.         MOV     BYTE PTR READ_MODE,1    ;2352 mode
  1219.         MOV     AH_SAVE,6               ;READ EXT
  1220. START_0:
  1221.         CMP     AH_SAVE,17H             ;MODE_SET command?
  1222.         JE      START_1
  1223.         CMP     MAX_DRIVE,0
  1224.         JNZ     START_2
  1225.         CALL    CHK_MAX
  1226. START_2:
  1227.         CMP     MAX_DRIVE,7
  1228.         JNZ     START_3
  1229. START_3:
  1230.         MOV     DL,DL_SAVE
  1231.         CMP     DL,MAX_DRIVE
  1232.         JBE     START_31
  1233.         JMP     short PAR_ER
  1234. START_31:
  1235.         SHL     DL,1
  1236.         SHL     DL,1
  1237.         SHL     DL,1
  1238.         OR      DL,MASK_DS0
  1239.         CMP     DL_SAVE,4
  1240.         JB      START_4                 ;DS0-3
  1241.         AND     DL,MASK_DS4             ;DS4-7
  1242. START_4:
  1243.         MOV     DRIVE_NO_MASK,DL        ;GET DRIVE SELECT MASK
  1244.         MOV     AH,AH_SAVE
  1245.         CMP     AH,18H
  1246.         JA      COM_ER
  1247. START_1:
  1248.         MOV     AL,AH_SAVE
  1249.         SHL     AL,1                    ;GET OFFSET INTO FUNCTION TABLE
  1250.         LEA     DI,FUNCTBL              ;GET ADDRESS OF FUNCTION TABLE
  1251.         XOR     AH,AH
  1252.         ADD     DI,AX                   ;GET JUMP VECTOR
  1253.         JMP     WORD PTR[DI]            ;JUMP TO FUNCTION
  1254. ;-----------------------------
  1255. ;       < MAX D_NO CHECK>
  1256. ;-----------------------------
  1257. CHK_MAX PROC    NEAR
  1258.         MOV     MAX_DRIVE,3
  1259.         PPI_CR          ;SET PPI PORT_A INPUT MODE
  1260.         MOV     AL,PAIN                 ;
  1261.         OUT     DX,AL                   ;    PPI_CR <- PAIN
  1262.         PPI_PC                  ;PPI_PC
  1263.         MOV     AL,CLR_IN               ;    LOAD CLEAR & BUS_DIR IN CODE
  1264.         OR      AL,MASK_DS0
  1265.         JMP     $+2
  1266.         OUT     DX,AL                   ;    CLEAR & BUS_DIR IN
  1267.  
  1268. CHK_MAX_0:
  1269.         PPI_PB
  1270.         IN      AL,DX                   ;LOAD PPI PORT_B
  1271.         AND     AL,03CH                 ;MASK DRIVE NO
  1272.         CMP     AL,24H                  ;CHECK I/F ID
  1273.         JE      CHK_MAX_1
  1274.         RET                             ;MAX 4 DIRVES
  1275. ;
  1276. CHK_MAX_1:
  1277.         PPI_PC                          ;PPI_PC
  1278.         MOV     AL,CLR_IN               ;    LOAD CLEAR & BUS_DIR IN CODE
  1279.         OR      AL,MASK_DS0
  1280.         OR      AL,18H                  ;DRIVE No.3
  1281.         JMP     $+2
  1282.         OUT     DX,AL                   ;    CLEAR & BUS_DIR IN
  1283. ;
  1284. CHK_MAX_00:
  1285.         PPI_PB
  1286.         IN      AL,DX                   ;LOAD PPI PORT_B
  1287.         AND     AL,03CH                 ;MASK DRIVE NO
  1288.         CMP     AL,3CH                  ;CHECK I/F ID
  1289.         JE      CHK_MAX_2
  1290.         RET                             ;MAX 4 DRIVES
  1291.  
  1292. CHK_MAX_2:
  1293.         MOV     MAX_DRIVE,7
  1294.         RET
  1295. CHK_MAX ENDP
  1296. ;-----------------------------
  1297. ;       < INT           >
  1298. ;-----------------------------
  1299. INT_OFF PROC    NEAR
  1300.         RET                     ;DUMMY
  1301. INT_OFF ENDP
  1302.  
  1303. ;-----------------------------
  1304. ;       < COMMON EXIT >
  1305. ;-----------------------------
  1306. N_RT:   XOR     AH,AH                   ;RESET CARRY
  1307.         CLC
  1308. EXIT:
  1309.         STI
  1310.         POP     SI                      ;RESTORE ALL OF THE REGISTERS
  1311.         POP     DI
  1312.         POP     DX
  1313.         POP     CX
  1314.         POP     BX
  1315.         POP     BP
  1316.         POP     ES
  1317.         POP     DS
  1318.         RET
  1319. ;-----------------------------
  1320. ;       < ERROR RETURN >
  1321. ;-----------------------------
  1322. COM_ER:
  1323. ERROR_COM:
  1324.         MOV     AH,BAD_COM              ;LOAD BAD_COMMAND CODE
  1325.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1326. PAR_ER: MOV     AH,BAD_PARA             ;LOAD BAD PARAMETER CODE
  1327.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1328. DR_ER:  MOV     AH,NOT_READY            ;LOAD DRIVE NOT READY CODE
  1329.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1330. SEK_ER: MOV     AH,SEEK_ER              ;LOAD SEEK ERROR CODE
  1331.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1332. TIM_ER: MOV     AH,TIME_OUT             ;LOAD TIME OUT ERROR CODE
  1333.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1334. OTHER:  MOV     AH,OTHER_ER             ;LOAD OTHER ERROR CODE
  1335.         JMP     SHORT ERR_RT            ;JUMP TO ERROR RETURN
  1336. ECC_ER: MOV     AH,BAD_ECC              ;LOAD BAD ECC ERROR CODE
  1337. ERR_RT: STC                             ;ERROR RETURN
  1338.         JMP     EXIT                    ;EXIT
  1339. ;----------------------------------------------------------------------
  1340. ;   INIT
  1341. ;
  1342. INIT:
  1343.         MOV     ERRCNT,RETRY2
  1344. ;
  1345. ; 07/16/90, don't reset the clock mode
  1346. ;       MOV     CLOCK_MODE,0FFH         ;CLEAR CLOCK MODE
  1347. ;
  1348.         CALL    GET_DRIVE_OFF
  1349.         MOV     BYTE PTR CURRENT_DRIVE[SI],0FFH
  1350.         PPI_CR
  1351.         MOV     AL,PAIN                 ;    PORT A,B  INPUT
  1352.         OUT     DX,AL                   ;    PORT C    OUTPUT
  1353.         DEC     DX                      ;    DX <-- PPI_PC_AD
  1354.         MOV     AL,CLR_IN               ;    CLEAR PPI_PC
  1355.         OR      AL,DRIVE_NO_MASK
  1356.         OUT     DX,AL                   ;        PORT_C <- 82H
  1357. INIT_1:
  1358.         CALL    RESET_COMMAND           ;ISSUE RESET COMMAND
  1359.         JZ      INIT_RETRY_1
  1360. INIT_2:
  1361.         CALL    CHK_DRV                 ;CHECK DRIVE TYPE
  1362.         JB      INIT_RETRY_3
  1363. INIT_4:
  1364.         CALL    CHK_DR                  ;CHECK DRIVE READY
  1365.         JZ      INIT_RETRY_2
  1366.         CALL    GET_DRIVE_OFF
  1367.         MOV     AL,BYTE PTR CURRENT_DRIVE[SI]
  1368.         JMP     N_RT
  1369. INIT_RETRY_1:
  1370.         DEC     ERRCNT
  1371.         JNZ     INIT_1
  1372.         JMP     SHORT INIT_TIM_ER
  1373. INIT_RETRY_2:
  1374.         DEC     ERRCNT
  1375.         JNZ     INIT_4
  1376.         CALL    GET_DRIVE_OFF
  1377.         MOV     AL,BYTE PTR CURRENT_DRIVE[SI]
  1378.         JMP     DR_ER                   ;ERROR!! DRIVE NOT READY
  1379. INIT_RETRY_3:
  1380.         DEC     ERRCNT
  1381.         JNZ     INIT_2
  1382. INIT_TIM_ER:
  1383.         CALL    GET_DRIVE_OFF
  1384.         MOV     AL,BYTE PTR CURRENT_DRIVE[SI]
  1385.         JMP     TIM_ER
  1386. ;----------------------------------------------------------------------
  1387. ; DISK READ
  1388. ;
  1389.  
  1390. ifdef DEBUG
  1391. public READ_EXT
  1392. endif
  1393.  
  1394. READ_EXT:
  1395.         MOV     AX,DI_SAVE
  1396.         MOV     CD_TOTAL,AX
  1397.         JMP     SHORT INPUT_READ
  1398. INPUT:
  1399.         MOV     AL,AL_SAVE
  1400.         XOR     AH,AH
  1401.         MOV     CD_TOTAL,AX
  1402. INPUT_READ:
  1403.         CMP     AX,0
  1404.         JE      INPUT_RD_ER
  1405. INPUT_RD_0:
  1406.         CALL    PARAMETER_CHECK
  1407.         JNC     INPUT_1
  1408. INPUT_RD_ER:
  1409.         JMP     PAR_ER
  1410. INPUT_1:
  1411.         MOV     TRNS_MODE,1             ;DMA
  1412.         CMP     CURRENT_IF_MODE,1       ;CANNOT SOFT TRNS ?
  1413.         JE      INPUT_0_B
  1414.         CMP     MODE_SET_TRNS,1         ;DMA MODE ?
  1415.         JE      INPUT_0_B
  1416.         CMP     CLOCK_MODE,80H
  1417.         JE      INPUT_0_B
  1418.         MOV     TRNS_MODE,0             ;SOFT TRNS
  1419. INPUT_0_B:
  1420.         XOR     AX,AX
  1421.         MOV     CD_CNT,AX               ;CLEAR CD_CNT
  1422. IN_00:
  1423.         MOV     BYTE PTR ERRCNT,RETRY   ;PRESET ERROR COUNTER
  1424. IN_5:
  1425.         XOR     AL,AL
  1426.         MOV     BYTE PTR PAUSE_FLG,AL   ;CLEAR PAUSE FLAG
  1427.         CALL    READ_COMMAND            ;READ ONE DATA BLOCK
  1428.         JNZ     IN_5_0
  1429.         CALL    READ_COMMAND
  1430.         JNZ     IN_5_0                  ;    JUMP IF ERROR
  1431.         JMP     INE_3                   ;TIME OUT ERROR
  1432. IN_5_0:
  1433.         CALL    CHK_DR_INPUT
  1434.         mov     time_2,T_OVER5
  1435.         call    set_time_2              ;SET 5 SEC
  1436.         JNZ     IN_NEXT
  1437. IN_5_1:
  1438.         JMP     INE_1
  1439. IN_1:   mov     time_2,T_OVER5
  1440.         call    set_time_2              ;SET 5 SEC
  1441. IN_10:  CALL    STATUS_COMMAND          ;    READ CD-ROM STATUS
  1442.         JZ      IN_5_1                  ;        JUMP IF ERROR
  1443.         MOV     BX,10
  1444. IN_10_S:
  1445.         DEC     BX
  1446.         JNZ     IN_10_S
  1447. IN_NEXT:
  1448.         MOV     AL,BYTE PTR STA_CODE    ;        LOAD STATUS
  1449.         AND     AL,0FEH                 ;        MASK BUSY
  1450.         JNZ     IN_6                    ;        JUMP IF SEEK COMPLETE
  1451. IN_NEXT_1:
  1452.  
  1453.         call    check_time_2
  1454.  
  1455.         JNZ     IN_10                   ;    LOOP UNTIL DATA READY
  1456. IN_NEXT_2:
  1457.         MOV     STA_CODE,SEEK_ERR
  1458.         JMP     short INE_1             ;    TIME OUT ERROR
  1459. IN_6:
  1460.  
  1461.         call    check_time_2
  1462.  
  1463.         JZ      IN_NEXT_2               ;    LOOP UNTIL DATA READY
  1464.         TEST    AL,62H                  ;   CHECK ERROR
  1465.         JNZ     INE_1
  1466.         TEST    AL,DATA_READY           ;    TEST DATA READY?
  1467.         JZ      IN_10                   ;    JUMP IF DATA IS NOT READY
  1468.         XOR     BX,BX
  1469. IN_6_1:
  1470.         DEC     BX
  1471.         JZ      INE_1                   ;TIME OUT
  1472.         IN_PB
  1473.         TEST    AL,BUS_BUSY
  1474.         JZ      IN_6_1
  1475.         MOV     AL,STA_CODE             ;------ added 4/2
  1476.         TEST    AL,DATA_ERR             ;    CHECK DATA ERROR?
  1477.         JNZ     IN_2                    ;    JUMP IF ERROR HAPPEND
  1478.         CALL    SECREAD                 ;    READ DATA
  1479.         JZ      IN_NEXT_2               ;    JUMP IF BAD ID
  1480.         JMP     SHORT IN_3              ;
  1481. IN_2:   CALL    ER_CORRECT              ;    READ DATA AND CORRECT ERROR
  1482.         JC      INE_8                   ;    JUMP IF BAD ECC
  1483.         JZ      IN_NEXT_2               ;    JUMP IF BAD ID
  1484.         JMP     SHORT IN_33
  1485. IN_3:
  1486.         CALL    STATUS_COMMAND
  1487.         JZ      INE_1                   ;TIME OUT
  1488.         TEST    BYTE PTR STA_CODE,62H   ;CHECK LOST DATA,SEEK ERROR,DR NOT READY
  1489.         JNZ     INE_1                   ;LOST DATA ERROR
  1490. IN_33:  INC     CD_CNT                  ;INCREMENT CD_CNT
  1491.         MOV     AX,CD_TOTAL
  1492.         CMP     AX,CD_CNT               ;DONE ALL BLOCKS?
  1493.         JNA     IN_RT                   ;JUMP IF ALL BLOCKS HAVE BEEN SENT
  1494. IN_4:
  1495.         CMP     READ_MODE,0
  1496.         JNE     IN_4_0
  1497.         CALL    UPDATE                  ;UPDATE DATA BLOCK
  1498.         JC      INE_5                   ;JUMP IF DATA BLOCK IS OUT OF RANGE
  1499.         JMP     SHORT IN_4_1
  1500. IN_4_0:
  1501.         CALL    UPDATE_2352
  1502.         JC      INE_5
  1503. IN_4_1:
  1504.         TEST    BYTE PTR PAUSE_FLG,0FFH ;CHECK DRIVE IS "PAUSE" OR NOT
  1505.         JZ      IN_7                    ;    JUMP IF DRIVE IS "PLAY"
  1506.         JMP     IN_00
  1507. IN_7:   MOV     BYTE PTR ERRCNT,RETRY   ;READ NEXT BLOCK
  1508.         mov     time_2,T_OVER5
  1509.         call    set_time_2              ;SET 5 SEC
  1510.         JMP     IN_NEXT                 ;
  1511. IN_RT:  CALL    PAUSE_COMMAND           ;ALL BLOCKS HAVE BEEN SENT, ISSUE PAUSE COMMAND
  1512.         JMP     N_RT                    ;NORMAL RETURN
  1513. INE_1:  DEC     BYTE PTR ERRCNT         ;DECREMENT ERROR COUNT
  1514.         JZ      INE_2                   ;NO MORE RETRY
  1515.         JMP     IN_5                    ;TRY AGAIN
  1516. INE_2:  MOV     AL,BYTE PTR STA_CODE    ;CHECK STATUS CODE
  1517.         TEST    AL,0FEH                 ;    TEST TIME OUT ERROR
  1518.         JZ      INE_3                   ;
  1519.         TEST    AL,DRIVE_READY          ;    TEST DRIVE READY
  1520.         JNZ     INE_4                   ;
  1521.         TEST    AL,SEEK_ERR             ;    TEST SEEK ERROR
  1522.         JNZ     INE_7                   ;
  1523.         JMP     OTHER                   ;OTHER ERROR
  1524. INE_8:
  1525.         DEC     BYTE PTR ERRCNT
  1526.         JZ      INE_6
  1527.         JMP     IN_5
  1528. INE_3:  JMP     TIM_ER                  ;TIME OUT ERROR
  1529. INE_4:  JMP     DR_ER                   ;DRIVE NOT READY
  1530. INE_5:  JMP     PAR_ER                  ;BAD PARAMETER
  1531. INE_6:  JMP     ECC_ER                  ;ECC ERROR
  1532. INE_7:  JMP     SEK_ER                  ;SEEK ERROR
  1533. ;----------------------------------------------------------------------
  1534. ;
  1535. ; SEEK
  1536. ;
  1537. ;----------------------------------------------------------------------
  1538. SEEK:   CALL    PARAMETER_CHECK         ;CHECK PARAMETERS
  1539.         JNC     SEEK_1
  1540.         JMP     PAR_ER                  ;PARAMETER ERROR
  1541. SEEK_1:
  1542.         MOV     ERRCNT,RETRY2
  1543. SEEK_2:
  1544.         CALL    SEEK_COMMAND            ;ISSUE SEEK COMMAND
  1545.         JZ      SEEK_RETRY              ;JUMP IF TIME OUT
  1546.         CALL    SEEK_ERROR_CHK
  1547.         JZ      SEEK_ER_TIM             ;TIME OUT
  1548.         JC      SEEK_RETRY              ;SEEK ERROR
  1549.         JMP     short N_RT_CHK          ;CHECK DRIVE READY
  1550. SEEK_RETRY:
  1551.         DEC     ERRCNT
  1552.         JNZ     SEEK_2
  1553. SEEK_CHECK_SUB:
  1554.         MOV     AL,STA_CODE
  1555.         TEST    AL,SEEK_ERR
  1556.         JNZ     SEEK_SEEK_ER
  1557.         TEST    AL,DRIVE_READY
  1558.         JNZ     SEEK_DR_RDY
  1559. SEEK_ER_TIM:
  1560.         JMP     TIM_ER
  1561. SEEK_SEEK_ER:
  1562.         JMP     SEK_ER
  1563. SEEK_DR_RDY:
  1564.         JMP     DR_ER
  1565. ;----------------------------------------------------------------------
  1566. ; ISSUE SEEK COMMAND AND WAIT UNTILL SEEK COMPLETE
  1567. ;
  1568. SEEKW:  CALL    PARAMETER_CHECK         ;CHECK PARAMETERS
  1569.         JNC     SEKW_0
  1570.         JMP     PAR_ER
  1571. SEKW_0:
  1572.         MOV     ERRCNT,RETRY2
  1573. SEKW_0_1:
  1574.         CALL    SEEK_COMMAND            ;ISSUE SEEK COMMAND
  1575.         JNZ     SEKW_0_2
  1576.         JMP     short SEKW_RETRY_1      ;JUMP IF TIME OUT ERROR
  1577. SEKW_0_2:
  1578. SEKW_1: CALL    SEEK_ERROR_CHK          ;ISSUE DISK STATUS COMMAND
  1579.         JZ      SEEK_ER_TIM             ;JUMP IF TIME OUT
  1580.         JC      SEKW_RETRY_1            ;SEEK ERROR
  1581. SEKW_2: mov     time_2,T_OVER3
  1582.         call    set_time_2              ;10 sec
  1583. SEKW_6: CALL    STATUS_COMMAND          ;    ISSUE DISK STATUS COMMAND
  1584.         JNZ     SEKW_7                  ;    JUMP IF TIME OUT
  1585.         JMP     TIM_ER
  1586. SEKW_7:
  1587.         MOV     AL,BYTE PTR STA_CODE    ;    CHECK SEEK COMPLETE
  1588.         TEST    AL,DRIVE_BUSY           ;        TEST DRIVE BUSY
  1589.         JZ      SEKW_4                  ;    JUMP IF DRIVE IS NOT BUSY
  1590.  
  1591.         call    check_time_2
  1592.  
  1593.         JNZ     SEKW_6                  ;LOOP UNTIL SEEK COMPLETE
  1594.         JMP     SEK_ER                  ;JUMP IF TIME OUT
  1595. SEKW_4: JMP     SHORT N_RT_CHK                  ;NORMAL RETURN
  1596. ;
  1597. SEKW_RETRY_1:
  1598.         DEC     ERRCNT
  1599.         JNZ     SEKW_0_1
  1600.         JMP     SEEK_CHECK_SUB
  1601. N_RT_CHK:
  1602.         CALL    CHK_DR
  1603.         JNZ     STATUS_S_2              ;NORMAL RETURN
  1604. N_RT_CHK_1:
  1605.         JMP     DR_ER                   ;DRIVE NOT READY
  1606. ;----------------------------------------------------------------------
  1607. ;
  1608. ; STATUS READ
  1609. ;
  1610. ;----------------------------------------------------------------------
  1611. STATUS:
  1612.         MOV     ERRCNT,RETRY2
  1613. STATUS_S_1:
  1614.         CALL    STATUS_COMMAND          ;ISSUE STATUS COMMAND
  1615.         JZ      STATUS_RETRY            ;JUMP IF TIME OUT ERROR
  1616.         MOV     AL,BYTE PTR STA_CODE    ;SET STATUS CODE IN AL
  1617. STATUS_S_2:
  1618.         JMP     N_RT
  1619. STATUS_RETRY:
  1620.         DEC     ERRCNT
  1621.         JNZ     STATUS_S_1
  1622.         JMP     TIM_ER
  1623. ;----------------------------------------------------------------------
  1624. ;
  1625. ; DISK STATUS READ
  1626. ;
  1627. ;----------------------------------------------------------------------
  1628. DISKST:
  1629.         MOV     ERRCNT,RETRY2
  1630. DISKST_1:
  1631.         CALL    DSKSTA_COMMAND          ;ISSUE DISK STATUS COMMAND
  1632.         JZ      DISKST_RETRY                    ;JUMP IF TIME OUT ERROR
  1633.         MOV     AL,BYTE PTR STA_CODE    ;SET DISK STATUS CODE IN AL
  1634.         JMP     N_RT                    ;
  1635. DISKST_RETRY:
  1636.         DEC     ERRCNT
  1637.         JNZ     DISKST_1
  1638.         JMP     TIM_ER
  1639. ;----------------------------------------------------------------------
  1640. ;
  1641. VERSION:
  1642. ;
  1643. ;----------------------------------------------------------------------
  1644.         MOV     ERRCNT,RETRY2
  1645. VERSION_1:
  1646.         CALL    VERSION_COMMAND
  1647.         JZ      VERSION_RETRY
  1648.         JMP     N_RT
  1649. VERSION_RETRY:
  1650.         DEC     ERRCNT
  1651.         JNZ     VERSION_1
  1652.         JMP     TIM_ER
  1653. ;--------------------------------------------------------------------
  1654. ;
  1655. SEEK_TO_LEAD:
  1656. ;
  1657. ;--------------------------------------------------------------------
  1658.         MOV     ERRCNT,RETRY2
  1659. SEEK_T_1:
  1660.         CALL    SEEK_LEAD_COMMAND
  1661.         JZ      SEEK_T_RETRY
  1662.         CALL    CHK_DR
  1663.         JZ      SEEK_T_RETRY
  1664.         JMP     N_RT
  1665. SEEK_T_RETRY:
  1666.         DEC     ERRCNT
  1667.         JNZ     SEEK_T_1
  1668. INE_3_S:
  1669.         JMP     SEEK_CHECK_SUB
  1670. ;-------------------------------------------------------------------
  1671. ;
  1672. READ_SUBQ:
  1673. ;
  1674. ;-------------------------------------------------------------------
  1675.         MOV     ERRCNT,RETRY2
  1676. READ_SUBQ_1:
  1677.         CALL    READ_SUBQ_COMMAND
  1678.         JZ      READ_SUBQ_RETRY
  1679.         JMP     N_RT
  1680. READ_SUBQ_RETRY:
  1681.         DEC     ERRCNT
  1682.         JNZ     READ_SUBQ_1
  1683. READ_SUBQ_ER:
  1684.         JMP     TIM_ER
  1685. ;-------------------------------------------------------------------
  1686. ;
  1687. AUDIO:
  1688. ;
  1689. ;-------------------------------------------------------------------
  1690.         CALL    AUDIO_CHECK
  1691.         JC      AUDIO_PAR_ER
  1692.         MOV     AL_SAVE,0               ;OUTPUT L & R channel
  1693. AUDIO_SUB:
  1694.         MOV     ERRCNT,RETRY2
  1695. AUDIO_1:
  1696.         CALL    AUDIO_COMMAND
  1697.         JZ      AUDIO_RETRY
  1698.         CALL    SEEK_ERROR_CHK
  1699.         JZ      READ_SUBQ_ER            ;TIME OUT
  1700.         JC      AUDIO_RETRY
  1701.         JMP     N_RT_CHK
  1702. AUDIO_RETRY:
  1703.         DEC     ERRCNT
  1704.         JNZ     AUDIO_1
  1705.         JMP     SEEK_CHECK_SUB
  1706. ;-------------------------------------------------------------------
  1707. ;
  1708. AUDIO_EXT:
  1709. ;
  1710. ;-------------------------------------------------------------------
  1711.         CALL    AUDIO_CHECK
  1712.         JC      AUDIO_PAR_ER
  1713.         CMP     AL_SAVE,3
  1714.         JA      AUDIO_PAR_ER
  1715.         JMP     AUDIO_SUB
  1716. ;-------------------------------------------------------------------
  1717. AUDIO_TNO:
  1718.         CMP     AL_SAVE,4
  1719.         JNB     AUDIO_PAR_ER
  1720.         CMP     CH_SAVE,100
  1721.         JAE     AUDIO_PAR_ER
  1722.         CMP     CL_SAVE,100
  1723.         JAE     AUDIO_PAR_ER
  1724.         MOV     AL,CL_SAVE
  1725.         CMP     AL,CH_SAVE
  1726.         JB      AUDIO_PAR_ER
  1727.         MOV     ERRCNT,RETRY2
  1728. AUDIO_TNO_1:
  1729.         CALL    AUDIO_TNO_COMMAND
  1730.         JNZ     AUDIO_TNO_2
  1731.         CALL    AUDIO_TNO_COMMAND
  1732.         JZ      OPEN_TIM                ;TIME OUT
  1733. AUDIO_TNO_2:
  1734.         CALL    SEEK_ERROR_CHK
  1735.         JZ      OPEN_TIM                ;TIME OUT
  1736.         JC      AUDIO_TNO_RETRY
  1737.         JMP     N_RT_CHK
  1738. AUDIO_TNO_RETRY:
  1739.         DEC     ERRCNT
  1740.         JNZ     AUDIO_TNO_1
  1741.         TEST    BYTE PTR STA_CODE,DRIVE_READY
  1742.         JNZ     AUDIO_TNO_DR
  1743.         JMP     SEK_ER
  1744. AUDIO_PAR_ER:
  1745.         JMP     PAR_ER
  1746. AUDIO_TNO_DR:
  1747.         JMP     DR_ER
  1748. ;-------------------------------------------------------------------
  1749. OPEN:
  1750.         MOV     ERRCNT,RETRY2
  1751. OPEN_1:
  1752.         CALL    OPEN_COMMAND
  1753.         JZ      OPEN_RETRY
  1754.         JMP     N_RT
  1755. OPEN_RETRY:
  1756.         DEC     ERRCNT
  1757.         JNZ     OPEN_1
  1758. OPEN_TIM:
  1759.         JMP     TIM_ER
  1760. ;-------------------------------------------------------------------
  1761. CLOSE:
  1762.         MOV     ERRCNT,RETRY2
  1763. CLOSE_1:
  1764.         CALL    CLOSE_COMMAND
  1765.         JZ      CLOSE_RETRY
  1766.         JMP     N_RT
  1767. CLOSE_RETRY:
  1768.         DEC     ERRCNT
  1769.         JNZ     CLOSE_1
  1770.         JMP     TIM_ER
  1771. ;-------------------------------------------------------------------
  1772. P_A_MED:
  1773.         CMP     AL_SAVE,3
  1774.         JB      P_A_MED_1
  1775.         JMP     PAR_ER
  1776. P_A_MED_1:
  1777.         MOV     ERRCNT,RETRY2
  1778. P_A_MED_2:
  1779.         CALL    P_A_MED_COMMAND
  1780.         JZ      P_A_MED_RETRY
  1781.         MOV     AL,BYTE PTR STA_CODE    ;SET STATUS CODE IN AL
  1782.         JMP     N_RT
  1783. P_A_MED_RETRY:
  1784.         DEC     ERRCNT
  1785.         JNZ     P_A_MED_2
  1786.         JMP     TIM_ER
  1787. ;-------------------------------------------------------------------
  1788. SET_POWER:
  1789.         CMP     AL_SAVE,20
  1790.         JBE     SET_POWER_1
  1791.         JMP     PAR_ER
  1792. SET_POWER_1:
  1793.         MOV     ERRCNT,RETRY2
  1794. SET_POWER_2:
  1795.         CALL    SET_POWER_COMMAND
  1796.         JZ      SET_POWER_RETRY
  1797.         JMP     N_RT
  1798. SET_POWER_RETRY:
  1799.         DEC     ERRCNT
  1800.         JNZ     SET_POWER_2
  1801.         JMP     TIM_ER
  1802. ;------------------------------------------------------------------
  1803. STOP:
  1804.         MOV     ERRCNT,RETRY2
  1805. STOP_1:
  1806.         CALL    STOP_COMMAND
  1807.         JZ      STOP_RETRY
  1808.         JMP     N_RT
  1809. STOP_RETRY:
  1810.         DEC     ERRCNT
  1811.         JNZ     STOP_1
  1812.         JMP     TIM_ER
  1813. ;------------------------------------------------------------------
  1814. PAUSE:
  1815.         MOV     ERRCNT,RETRY2
  1816. PAUSE_1:
  1817.         CALL    PAUSE_COMMAND
  1818.         JZ      PAUSE_RETRY
  1819.         CALL    CHK_DR
  1820.         JZ      PAUSE_RETRY
  1821.         JMP     N_RT
  1822. PAUSE_RETRY:
  1823.         DEC     ERRCNT
  1824.         JNZ     PAUSE_1
  1825.         JMP     SEEK_CHECK_SUB
  1826. ;------------------------------------------------------------------
  1827. MODE_SET:
  1828.  
  1829.         MOV     AL,AL_SAVE
  1830.         CMP     AL,2
  1831.         JB      MODE_SET_AUTO
  1832.         JE      MODE_SET_1
  1833. MODE_SET_ER:
  1834.         JMP     PAR_ER
  1835. MODE_SET_1:
  1836.         MOV     MAX_DRIVE,0     ;CLEAR FLAG
  1837.         CALL    NEW_IF
  1838.         JC      MODE_SET_ER
  1839.         JMP     SHORT MODE_N_RT
  1840. MODE_SET_AUTO:
  1841.         MOV     MODE_SET_TRNS,AL
  1842. MODE_N_RT:
  1843.         JMP     N_RT
  1844. ;------------------------------------------------------------------
  1845. UCOM:
  1846.         MOV     ERRCNT,RETRY2
  1847. UCOM_1:
  1848.         CALL    UCOM_COMMAND
  1849.         JZ      UCOM_RETRY
  1850.         JMP     N_RT
  1851. UCOM_RETRY:
  1852.         DEC     ERRCNT
  1853.         JNZ     UCOM_1
  1854.         JMP     TIM_ER
  1855. ;-------------------------------------------------------------------
  1856. CH_CTRL:
  1857.         CMP     AL_SAVE,3
  1858.         JBE     CH_CTRL_1
  1859.         JMP     PAR_ER
  1860. CH_CTRL_1:
  1861.         MOV     ERRCNT,RETRY2
  1862. CH_CTRL_2:
  1863.         CALL    CH_CTRL_COMMAND
  1864.         JZ      CH_CTRL_RETRY
  1865.         MOV     AL,BYTE PTR STA_CODE    ;SET STATUS CODE IN AL
  1866.         JMP     N_RT
  1867. CH_CTRL_RETRY:
  1868.         DEC     ERRCNT
  1869.         JNZ     CH_CTRL_2
  1870.         JMP     TIM_ER
  1871. ;-------------------------------------------------------------------
  1872. ;-------------------------------------------------------------------
  1873. ;------------------------------------------------------------------
  1874. GENERAL:
  1875.         MOV     SI,SI_SAVE
  1876.         MOV     AX,DI_SAVE
  1877.         MOV     ES,AX
  1878.         CMP     ES:WORD PTR [SI],'IH'
  1879.         JNE     GENERAL_1               ;COMMAND ERROR
  1880.         CALL    GENERAL_COMMAND
  1881.         JNZ     MODE_N_RT
  1882.         CALL    GENERAL_COMMAND
  1883.         JNZ     MODE_N_RT
  1884.         JMP     TIM_ER
  1885. GENERAL_1:
  1886.         JMP     ERROR_COM
  1887. ;---------------------------------------------
  1888. ;       CHECK SEEK ERROR
  1889. ;               OUTPUT: ZR=1   -- TIME OUT
  1890. ;                       CY=1   -- SEEK ERROR
  1891. ;                       ZR=CY=0 - OK
  1892. ;---------------------------------------------
  1893. SEEK_ERROR_CHK          PROC    NEAR
  1894.         mov     time_2,T_OVER3
  1895.         call    set_time_2              ;SET 10 SEC
  1896. SEEK_ERR_CHK_0:
  1897.         MOV     STA_CODE,0
  1898.         CALL    STATUS_COMMAND
  1899.         JNZ     SEEK_ERR_CHK_1
  1900.         MOV     STA_CODE,0
  1901.         CALL    STATUS_COMMAND
  1902.         JNZ     SEEK_ERR_CHK_1
  1903.         RET                             ;TIME OVER
  1904. SEEK_ERR_CHK_1:
  1905.         MOV     AL,STA_CODE
  1906.         TEST    AL,SEEK_ERR
  1907.         JNZ     SEEK_ERR_NG             ;SEEK ERROR
  1908.         TEST    AL,DRIVE_BUSY
  1909.         JNZ     SEEK_ERR_CHK_2
  1910.  
  1911.         call    check_time_2
  1912.  
  1913.         JNZ     SEEK_ERR_CHK_0
  1914. SEEK_ERR_NG:
  1915.         OR      AL,1
  1916.         STC
  1917.         RET
  1918. SEEK_ERR_CHK_2:
  1919.         OR      AL,1                    ;RESET ZR
  1920.         CLC                             ;OK
  1921.         RET
  1922. SEEK_ERROR_CHK          ENDP
  1923. ;--------------------------------------
  1924. PARAMETER_CHECK         PROC    NEAR
  1925.         CMP     CD_MIN,MAX_MINUTE
  1926.         JAE     PARAMETER_ERROR
  1927.         CMP     CD_SEC,MAX_SECOND
  1928.         JAE     PARAMETER_ERROR
  1929.         CMP     CD_BLK,MAX_BLOCK
  1930.         JAE     PARAMETER_ERROR
  1931. PARAMETER_ERROR:
  1932.         CMC
  1933.         RET
  1934. PARAMETER_CHECK         ENDP
  1935. ;----------------------------------------
  1936. AUDIO_CHECK     PROC    NEAR
  1937.         MOV     BX,MYDTA_OFF
  1938.         MOV     AX,MYDTA_SEG
  1939.         MOV     DS,AX
  1940.         CMP     BYTE PTR [BX],MAX_MINUTE
  1941.         JAE     AUDIO_CHK_ERROR
  1942.         CMP     BYTE PTR [BX+1],MAX_SECOND
  1943.         JAE     AUDIO_CHK_ERROR
  1944.         CMP     BYTE PTR [BX+2],MAX_BLOCK
  1945.         JAE     AUDIO_CHK_ERROR
  1946.         CMP     BYTE PTR [BX+3],MAX_MINUTE
  1947.         JAE     AUDIO_CHK_ERROR
  1948.         CMP     BYTE PTR [BX+4],MAX_SECOND
  1949.         JAE     AUDIO_CHK_ERROR
  1950.         CMP     BYTE PTR [BX+5],MAX_BLOCK
  1951. AUDIO_CHK_ERROR:
  1952.         MOV     AX,CS
  1953.         MOV     DS,AX
  1954.         CMC
  1955.         RET
  1956. AUDIO_CHECK     ENDP
  1957.  
  1958. ;----------------------------------------------------------------------
  1959. ;       NEW IF
  1960. ;----------------------------------------------------------------------
  1961. NEW_IF          PROC    NEAR
  1962.         MOV     AX,CS
  1963.         MOV     ES,AX
  1964.         MOV     AL,CL_SAVE
  1965.         MOV     AH,CH_SAVE
  1966.         CMP     AX,100H
  1967.         JB      NEW_IF_ER
  1968.         CMP     AX,3FFH
  1969.         JA      NEW_IF_ER
  1970.         AND     AX,03F0H        ;GET NEW I/F ADDRESS
  1971.         CMP     AX,CURRENT_IF
  1972.         JE      NEW_IF_RET
  1973.         MOV     CURRENT_IF,AX
  1974.         MOV     DI,OFFSET CURRENT_IF_MODE
  1975.         MOV     AL,0FFH
  1976.         MOV     CX,9            ;1+8
  1977.         REP     STOSB
  1978. NEW_IF_RET:
  1979.         CLC
  1980.         RET
  1981. NEW_IF_ER:
  1982.         STC
  1983.         RET
  1984. NEW_IF          ENDP
  1985.  
  1986.  
  1987. ;---------------------------------------------------------------------
  1988. ;       check drive type
  1989. ;---------------------------------------------------------------------
  1990. CHK_DRV         PROC    NEAR
  1991. CHK_DRV_LOOP_1:
  1992.         MOV     TWICE,1
  1993. CHK_DRV_LOOP_2:
  1994.         MOV     AX,CS
  1995.         MOV     ES_SAVE,AX
  1996.         MOV     AX,OFFSET BUF
  1997.         MOV     BX_SAVE,AX
  1998.         CALL    VERSION_COMMAND
  1999.         JNE     CHK_DRV_23_1
  2000.         CALL    VERSION_COMMAND
  2001.         JZ      CHK_TIM_ER
  2002. CHK_DRV_23_1:
  2003.         CMP     WORD PTR BUF,0FFFFH
  2004.         JE      CHK_DRV_12
  2005.         MOV     AL,BYTE PTR BUF+51
  2006.         AND     AL,7FH
  2007.         JMP     SHORT CHK_DRV_TWICE
  2008. ;
  2009. CHK_DRV_12:                             ;CHECK 1502 OR 2500
  2010.         CALL    READ_PORT_COMMAND
  2011.         JNZ     CHK_DRV_1
  2012.         CALL    READ_PORT_COMMAND
  2013.         JZ      CHK_TIM_ER
  2014. CHK_DRV_1:
  2015.         MOV     AL,20H
  2016.         CMP     WORD PTR BUF+2,0FFFFH
  2017.         JNE     CHK_DRV_TWICE
  2018.         CMP     WORD PTR BUF+6,0FFFFH
  2019.         JNE     CHK_DRV_TWICE
  2020.         XOR     AL,AL
  2021. CHK_DRV_TWICE:
  2022.         CMP     TWICE,0
  2023.         JE      CHK_DRV_2
  2024.         MOV     CHK_DRV_WORK,AL
  2025.         DEC     TWICE
  2026.         JMP     CHK_DRV_LOOP_2          ;2nd CHECK
  2027. ;
  2028. CHK_TIM_ER:
  2029.         STC
  2030. ;       JMP     CHK_DRV_4
  2031.         RET
  2032. ;
  2033. CHK_DRV_2:
  2034.         CMP     AL,CHK_DRV_WORK
  2035.         JE      CHK_DRV_3
  2036.         MOV     CHK_DRV_WORK,AL
  2037.         JMP     CHK_DRV_LOOP_1          ;TRY AGAIN
  2038. CHK_DRV_3:
  2039.         CALL    GET_DRIVE_OFF
  2040.         MOV     BYTE PTR CURRENT_DRIVE[SI],AL
  2041.         CLC
  2042. CHK_DRV_4:
  2043. ;       POP     AX
  2044.         RET
  2045. ;
  2046. GET_DRIVE_OFF:
  2047.         PUSH    DX
  2048.         MOV     DL,CS:DL_SAVE
  2049.         XOR     DH,DH
  2050.         MOV     SI,DX   ;OFFSET
  2051.         POP     DX
  2052.         RET
  2053. CHK_DRV         ENDP
  2054.  
  2055.  
  2056. ;---------------------------------------------------------------------
  2057. ;
  2058. ; set_time_1() - check_time_1()
  2059. ; set_time_2() - check_time_2()
  2060. ;
  2061. ; Uses the 18Hz system timer long integer located at 40:6C to establish
  2062. ; timing wait loops for CDREAD routines.
  2063. ;
  2064. ;---------------------------------------------------------------------
  2065. set_time_1 proc near
  2066.         pushf
  2067.         push    bx
  2068.         push    ds
  2069.         mov     bx,40h
  2070.         mov     ds,bx
  2071.         mov     bx,06ch
  2072.         mov     bx,word ptr [bx]
  2073.         pop     ds
  2074.         add     word ptr time_1,bx
  2075.         pop     bx
  2076.         popf
  2077.         ret
  2078. set_time_1 endp
  2079.  
  2080. set_time_2 proc near
  2081.         pushf
  2082.         push    bx
  2083.         push    ds
  2084.         mov     bx,40h
  2085.         mov     ds,bx
  2086.         mov     bx,06ch
  2087.         mov     bx,word ptr [bx]
  2088.         pop     ds
  2089.         add     word ptr time_2,bx
  2090.         pop     bx
  2091.         popf
  2092.         ret
  2093. set_time_2 endp
  2094.  
  2095. check_time_1 proc near
  2096.         push    ax
  2097.         push    bx
  2098.         push    ds
  2099.         mov     ax,40h
  2100.         mov     ds,ax
  2101.         mov     bx,06ch
  2102.         mov     ax,word ptr [bx]
  2103.         pop     ds
  2104.         cmp     ax,word ptr time_1
  2105.         jb      @f
  2106.         xor     ax,ax
  2107. @@:     pop     bx
  2108.         pop     ax
  2109.         ret
  2110. check_time_1 endp
  2111.  
  2112. check_time_2 proc near
  2113.         push    ax
  2114.         push    bx
  2115.         push    ds
  2116.         mov     ax,40h
  2117.         mov     ds,ax
  2118.         mov     bx,06ch
  2119.         mov     ax,word ptr [bx]
  2120.         pop     ds
  2121.         cmp     ax,word ptr time_2
  2122.         jb      @f
  2123.         xor     ax,ax
  2124. @@:     pop     bx
  2125.         pop     ax
  2126.         ret
  2127. check_time_2 endp
  2128.  
  2129.  
  2130. CDREAD ENDP
  2131.  
  2132. _TEXT   ENDS
  2133.         END BEGIN
  2134.